2022-06-01 21:41:57 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "GeometryCollection/GeometryCollectionEngineConversion.h"
# include "AssetRegistry/AssetRegistryModule.h"
# include "AnimationRuntime.h"
# include "Async/ParallelFor.h"
# include "Components/SkeletalMeshComponent.h"
# include "Components/StaticMeshComponent.h"
# include "Engine/Selection.h"
# include "Engine/StaticMesh.h"
# include "GameFramework/Actor.h"
2022-09-21 11:52:44 -04:00
# include "GeometryCollection/Facades/CollectionTransformSourceFacade.h"
2022-06-01 21:41:57 -04:00
# include "GeometryCollection/GeometryCollection.h"
# include "GeometryCollection/GeometryCollectionActor.h"
# include "GeometryCollection/GeometryCollectionAlgo.h"
# include "GeometryCollection/GeometryCollectionComponent.h"
# include "GeometryCollection/GeometryCollectionClusteringUtility.h"
# include "GeometryCollectionProxyData.h"
# include "GeometryCollection/GeometryCollectionUtility.h"
# include "Logging/LogMacros.h"
# include "Materials/Material.h"
# include "Rendering/SkeletalMeshRenderData.h"
# include "MeshDescription.h"
# include "StaticMeshAttributes.h"
# include "StaticMeshOperations.h"
# include "Physics/Experimental/ChaosInterfaceUtils.h"
2022-06-23 17:00:03 -04:00
# include "PhysicsEngine/BodySetup.h"
2022-08-18 15:37:22 -04:00
# include "MeshDescriptionBuilder.h"
# include "VertexConnectedComponents.h"
2022-06-01 21:41:57 -04:00
DEFINE_LOG_CATEGORY_STATIC ( UGeometryCollectionConversionLogging , Log , All ) ;
struct FUniqueVertex
{
FVector3f Normal ;
FVector3f Tangent ;
TArray < FVector2f > UVs ;
bool operator = = ( const FUniqueVertex & Other ) const
{
if ( this - > UVs . Num ( ) ! = Other . UVs . Num ( ) )
{
return false ;
}
bool bEquality = true ;
bEquality & = ( this - > Normal = = Other . Normal ) ;
bEquality & = ( this - > Tangent = = Other . Tangent ) ;
for ( int32 UVLayerIdx = 0 ; UVLayerIdx < UVs . Num ( ) ; + + UVLayerIdx )
{
bEquality & = ( this - > UVs [ UVLayerIdx ] = = Other . UVs [ UVLayerIdx ] ) ;
}
return bEquality ;
}
} ;
FORCEINLINE uint32 GetTypeHash ( const FUniqueVertex & UniqueVertex )
{
uint32 VertexHash = GetTypeHash ( UniqueVertex . Normal ) ;
VertexHash = HashCombine ( VertexHash , GetTypeHash ( UniqueVertex . Tangent ) ) ;
for ( int32 UVLayerIdx = 0 ; UVLayerIdx < UniqueVertex . UVs . Num ( ) ; + + UVLayerIdx )
{
VertexHash = HashCombine ( VertexHash , GetTypeHash ( UniqueVertex . UVs [ UVLayerIdx ] ) ) ;
}
return VertexHash ;
}
2022-06-06 21:10:52 -04:00
static bool IsImportableImplicitObjectType ( Chaos : : EImplicitObjectType Type )
{
const Chaos : : EImplicitObjectType InnerType = Type & ( ~ ( Chaos : : ImplicitObjectType : : IsScaled | Chaos : : ImplicitObjectType : : IsInstanced ) ) ;
return ( InnerType = = Chaos : : ImplicitObjectType : : Box | | InnerType = = Chaos : : ImplicitObjectType : : Sphere | | InnerType = = Chaos : : ImplicitObjectType : : Capsule | | InnerType = = Chaos : : ImplicitObjectType : : Convex ) ;
}
2022-06-24 12:28:07 -04:00
static FVector GetMeshBuildScale3D ( const UStaticMesh & StaticMesh )
{
# if WITH_EDITOR
const TArray < FStaticMeshSourceModel > & SourceModels = StaticMesh . GetSourceModels ( ) ;
if ( SourceModels . Num ( ) > 0 )
{
return SourceModels [ 0 ] . BuildSettings . BuildScale3D ;
}
# endif
return FVector : : One ( ) ;
}
2022-06-23 17:00:03 -04:00
void FGeometryCollectionEngineConversion : : AppendMeshDescription (
const FMeshDescription * MeshDescription , const FString & Name , int32 MaterialStartIndex , const FTransform & StaticMeshTransform ,
2022-08-18 15:37:22 -04:00
FGeometryCollection * GeometryCollection , UBodySetup * BodySetup , bool ReindexMaterials , bool bAddInternalMaterials )
2022-06-01 21:41:57 -04:00
{
# if WITH_EDITORONLY_DATA
2022-06-23 17:00:03 -04:00
if ( ! MeshDescription )
2022-06-01 21:41:57 -04:00
{
return ;
}
2022-06-23 17:00:03 -04:00
check ( GeometryCollection ) ;
// source vertex information
FStaticMeshConstAttributes Attributes ( * MeshDescription ) ;
TArrayView < const FVector3f > SourcePosition = Attributes . GetVertexPositions ( ) . GetRawArray ( ) ;
TArrayView < const FVector3f > SourceTangent = Attributes . GetVertexInstanceTangents ( ) . GetRawArray ( ) ;
TArrayView < const float > SourceBinormalSign = Attributes . GetVertexInstanceBinormalSigns ( ) . GetRawArray ( ) ;
TArrayView < const FVector3f > SourceNormal = Attributes . GetVertexInstanceNormals ( ) . GetRawArray ( ) ;
TArrayView < const FVector4f > SourceColor = Attributes . GetVertexInstanceColors ( ) . GetRawArray ( ) ;
TVertexInstanceAttributesConstRef < FVector2f > InstanceUVs = Attributes . GetVertexInstanceUVs ( ) ;
const int32 NumUVLayers = InstanceUVs . GetNumChannels ( ) ;
TArray < TArrayView < const FVector2f > > SourceUVArrays ;
SourceUVArrays . SetNum ( NumUVLayers ) ;
for ( int32 UVLayerIdx = 0 ; UVLayerIdx < NumUVLayers ; + + UVLayerIdx )
{
SourceUVArrays [ UVLayerIdx ] = InstanceUVs . GetRawArray ( UVLayerIdx ) ;
}
// target vertex information
TManagedArray < FVector3f > & TargetVertex = GeometryCollection - > Vertex ;
TManagedArray < FVector3f > & TargetTangentU = GeometryCollection - > TangentU ;
TManagedArray < FVector3f > & TargetTangentV = GeometryCollection - > TangentV ;
TManagedArray < FVector3f > & TargetNormal = GeometryCollection - > Normal ;
TManagedArray < TArray < FVector2f > > & TargetUVs = GeometryCollection - > UVs ;
TManagedArray < FLinearColor > & TargetColor = GeometryCollection - > Color ;
TManagedArray < int32 > & TargetBoneMap = GeometryCollection - > BoneMap ;
TManagedArray < FLinearColor > & TargetBoneColor = GeometryCollection - > BoneColor ;
TManagedArray < FString > & TargetBoneName = GeometryCollection - > BoneName ;
const int32 VertexStart = GeometryCollection - > NumElements ( FGeometryCollection : : VerticesGroup ) ;
int32 VertexCount = 0 ;
FVector Scale = StaticMeshTransform . GetScale3D ( ) ;
// We'll need to re-introduce UV seams, etc. by splitting vertices.
// A new mapping of MeshDescription vertex instances to the split vertices is maintained.
TMap < FVertexInstanceID , int32 > VertexInstanceToGeometryCollectionVertex ;
VertexInstanceToGeometryCollectionVertex . Reserve ( Attributes . GetVertexInstanceNormals ( ) . GetNumElements ( ) ) ;
for ( const FVertexID VertexIndex : MeshDescription - > Vertices ( ) . GetElementIDs ( ) )
{
TArrayView < const FVertexInstanceID > ReferencingVertexInstances = MeshDescription - > GetVertexVertexInstanceIDs ( VertexIndex ) ;
// Generate per instance hash of splittable attributes.
TMap < FUniqueVertex , TArray < FVertexInstanceID > > SplitVertices ;
for ( const FVertexInstanceID & InstanceID : ReferencingVertexInstances )
{
TArray < FVector2f > SourceUVs ;
SourceUVs . SetNum ( NumUVLayers ) ;
for ( int32 UVLayerIdx = 0 ; UVLayerIdx < NumUVLayers ; + + UVLayerIdx )
{
SourceUVs [ UVLayerIdx ] = SourceUVArrays [ UVLayerIdx ] [ InstanceID ] ;
}
FUniqueVertex UniqueVertex { SourceNormal [ InstanceID ] , SourceTangent [ InstanceID ] , SourceUVs } ;
TArray < FVertexInstanceID > & SplitVertex = SplitVertices . FindOrAdd ( UniqueVertex ) ;
SplitVertex . Add ( InstanceID ) ;
}
int32 CurrentVertex = GeometryCollection - > AddElements ( SplitVertices . Num ( ) , FGeometryCollection : : VerticesGroup ) ;
// Create a new vertex for each split vertex and map the mesh description instance to it.
for ( const TTuple < FUniqueVertex , TArray < FVertexInstanceID > > & SplitVertex : SplitVertices )
{
const TArray < FVertexInstanceID > & InstanceIDs = SplitVertex . Value ;
const FVertexInstanceID & ExemplarInstanceID = InstanceIDs [ 0 ] ;
TargetVertex [ CurrentVertex ] = SourcePosition [ VertexIndex ] * ( FVector3f ) Scale ;
TargetBoneMap [ CurrentVertex ] = GeometryCollection - > NumElements ( FGeometryCollection : : TransformGroup ) ;
TargetNormal [ CurrentVertex ] = SourceNormal [ ExemplarInstanceID ] ;
TargetTangentU [ CurrentVertex ] = SourceTangent [ ExemplarInstanceID ] ;
TargetTangentV [ CurrentVertex ] = ( FVector3f ) SourceBinormalSign [ ExemplarInstanceID ] * FVector3f : : CrossProduct ( TargetNormal [ CurrentVertex ] , TargetTangentU [ CurrentVertex ] ) ;
TargetUVs [ CurrentVertex ] = SplitVertex . Key . UVs ;
if ( SourceColor . Num ( ) > 0 )
{
TargetColor [ CurrentVertex ] = FLinearColor ( SourceColor [ ExemplarInstanceID ] ) ;
}
else
{
TargetColor [ CurrentVertex ] = FLinearColor : : White ;
}
for ( const FVertexInstanceID & InstanceID : InstanceIDs )
{
VertexInstanceToGeometryCollectionVertex . Add ( InstanceID , CurrentVertex ) ;
}
+ + CurrentVertex ;
+ + VertexCount ;
}
}
// target triangle indices
TManagedArray < FIntVector > & TargetIndices = GeometryCollection - > Indices ;
TManagedArray < bool > & TargetVisible = GeometryCollection - > Visible ;
TManagedArray < int32 > & TargetMaterialID = GeometryCollection - > MaterialID ;
TManagedArray < int32 > & TargetMaterialIndex = GeometryCollection - > MaterialIndex ;
const int32 IndicesCount = MeshDescription - > Triangles ( ) . Num ( ) ;
const int32 InitialNumIndices = GeometryCollection - > NumElements ( FGeometryCollection : : FacesGroup ) ;
const int32 IndicesStart = GeometryCollection - > AddElements ( IndicesCount , FGeometryCollection : : FacesGroup ) ;
int32 TargetIndex = IndicesStart ;
for ( const int32 TriangleIndex : MeshDescription - > Triangles ( ) . GetElementIDs ( ) )
{
TArrayView < const FVertexInstanceID > TriangleVertices = MeshDescription - > GetTriangleVertexInstances ( TriangleIndex ) ;
TargetIndices [ TargetIndex ] = FIntVector (
VertexInstanceToGeometryCollectionVertex [ TriangleVertices [ 0 ] ] ,
VertexInstanceToGeometryCollectionVertex [ TriangleVertices [ 1 ] ] ,
VertexInstanceToGeometryCollectionVertex [ TriangleVertices [ 2 ] ]
) ;
TargetVisible [ TargetIndex ] = true ;
2022-08-18 15:37:22 -04:00
// If adding internal materials, then materials are ganged in pairs and we want the id to associate with the first of each pair.
int32 MaterialIndexScale = 1 + int32 ( bAddInternalMaterials ) ;
TargetMaterialID [ TargetIndex ] = MaterialStartIndex + ( MeshDescription - > GetTrianglePolygonGroup ( TriangleIndex ) * MaterialIndexScale ) ;
2022-06-23 17:00:03 -04:00
// Is this right?
TargetMaterialIndex [ TargetIndex ] = TargetIndex ;
+ + TargetIndex ;
}
// Geometry transform
TManagedArray < FTransform > & Transform = GeometryCollection - > Transform ;
int32 TransformIndex1 = GeometryCollection - > AddElements ( 1 , FGeometryCollection : : TransformGroup ) ;
Transform [ TransformIndex1 ] = StaticMeshTransform ;
Transform [ TransformIndex1 ] . SetScale3D ( FVector ( 1.f , 1.f , 1.f ) ) ;
// collisions
if ( BodySetup )
{
TArray < TUniquePtr < Chaos : : FImplicitObject > > Geoms ;
Chaos : : FShapesArray Shapes ;
FGeometryAddParams CreateGeometryParams ;
CreateGeometryParams . bDoubleSided = false ;
CreateGeometryParams . CollisionData . CollisionFlags . bEnableQueryCollision = true ;
CreateGeometryParams . CollisionData . CollisionFlags . bEnableSimCollisionComplex = false ; // no support for trimesh in destruction
CreateGeometryParams . CollisionData . CollisionFlags . bEnableSimCollisionSimple = true ;
CreateGeometryParams . CollisionTraceType = ECollisionTraceFlag : : CTF_UseSimpleAsComplex ;
CreateGeometryParams . Scale = Scale ;
CreateGeometryParams . LocalTransform = Chaos : : FRigidTransform3 : : Identity ;
CreateGeometryParams . WorldTransform = Chaos : : FRigidTransform3 : : Identity ;
CreateGeometryParams . Geometry = & BodySetup - > AggGeom ;
CreateGeometryParams . ChaosTriMeshes = MakeArrayView ( BodySetup - > ChaosTriMeshes ) ;
// todo(chaos) : this currently also create the shape array which is unnecessary ,this could be optimized by having a common function to create only the implicits
ChaosInterface : : CreateGeometry ( CreateGeometryParams , Geoms , Shapes ) ;
using FCollisionType = FGeometryDynamicCollection : : FSharedImplicit ;
TManagedArray < FCollisionType > & ExternaCollisions = GeometryCollection - > AddAttribute < FCollisionType > ( " ExternalCollisions " , FGeometryCollection : : TransformGroup ) ;
ExternaCollisions [ TransformIndex1 ] = nullptr ;
for ( int32 GeomIndex = 0 ; GeomIndex < Geoms . Num ( ) ; )
{
// make sure we only import box, sphere, capsule or convex
if ( IsImportableImplicitObjectType ( Geoms [ GeomIndex ] - > GetType ( ) ) )
{
GeomIndex + + ;
}
else
{
Geoms . RemoveAtSwap ( GeomIndex ) ;
}
}
if ( Geoms . Num ( ) > 0 )
{
ExternaCollisions [ TransformIndex1 ] = MakeShared < Chaos : : FImplicitObjectUnion > ( MoveTemp ( Geoms ) ) ;
}
}
// Bone Hierarchy - Added at root with no common parent
TManagedArray < int32 > & Parent = GeometryCollection - > Parent ;
TManagedArray < int32 > & SimulationType = GeometryCollection - > SimulationType ;
Parent [ TransformIndex1 ] = FGeometryCollection : : Invalid ;
SimulationType [ TransformIndex1 ] = FGeometryCollection : : ESimulationTypes : : FST_Rigid ;
const FColor RandBoneColor ( FMath : : Rand ( ) % 100 + 5 , FMath : : Rand ( ) % 100 + 5 , FMath : : Rand ( ) % 100 + 5 , 255 ) ;
TargetBoneColor [ TransformIndex1 ] = FLinearColor ( RandBoneColor ) ;
TargetBoneName [ TransformIndex1 ] = Name ;
// GeometryGroup
int GeometryIndex = GeometryCollection - > AddElements ( 1 , FGeometryCollection : : GeometryGroup ) ;
TManagedArray < int32 > & TransformIndex = GeometryCollection - > TransformIndex ;
TManagedArray < FBox > & BoundingBox = GeometryCollection - > BoundingBox ;
TManagedArray < float > & InnerRadius = GeometryCollection - > InnerRadius ;
TManagedArray < float > & OuterRadius = GeometryCollection - > OuterRadius ;
TManagedArray < int32 > & VertexStartArray = GeometryCollection - > VertexStart ;
TManagedArray < int32 > & VertexCountArray = GeometryCollection - > VertexCount ;
TManagedArray < int32 > & FaceStartArray = GeometryCollection - > FaceStart ;
TManagedArray < int32 > & FaceCountArray = GeometryCollection - > FaceCount ;
TransformIndex [ GeometryIndex ] = TargetBoneMap [ VertexStart ] ;
VertexStartArray [ GeometryIndex ] = VertexStart ;
VertexCountArray [ GeometryIndex ] = VertexCount ;
FaceStartArray [ GeometryIndex ] = InitialNumIndices ;
FaceCountArray [ GeometryIndex ] = IndicesCount ;
// TransformGroup
TManagedArray < int32 > & TransformToGeometryIndexArray = GeometryCollection - > TransformToGeometryIndex ;
TransformToGeometryIndexArray [ TransformIndex1 ] = GeometryIndex ;
FVector Center ( 0 ) ;
for ( int32 VertexIndex = VertexStart ; VertexIndex < VertexStart + VertexCount ; VertexIndex + + )
{
Center + = ( FVector ) TargetVertex [ VertexIndex ] ;
}
if ( VertexCount ) Center / = VertexCount ;
// Inner/Outer edges, bounding box
BoundingBox [ GeometryIndex ] = FBox ( ForceInitToZero ) ;
InnerRadius [ GeometryIndex ] = FLT_MAX ;
OuterRadius [ GeometryIndex ] = - FLT_MAX ;
for ( int32 VertexIndex = VertexStart ; VertexIndex < VertexStart + VertexCount ; VertexIndex + + )
{
BoundingBox [ GeometryIndex ] + = ( FVector ) TargetVertex [ VertexIndex ] ;
float Delta = ( Center - ( FVector ) TargetVertex [ VertexIndex ] ) . Size ( ) ;
InnerRadius [ GeometryIndex ] = FMath : : Min ( InnerRadius [ GeometryIndex ] , Delta ) ;
OuterRadius [ GeometryIndex ] = FMath : : Max ( OuterRadius [ GeometryIndex ] , Delta ) ;
}
// Inner/Outer centroid
for ( int fdx = IndicesStart ; fdx < IndicesStart + IndicesCount ; fdx + + )
{
FVector Centroid ( 0 ) ;
for ( int e = 0 ; e < 3 ; e + + )
{
Centroid + = ( FVector ) TargetVertex [ TargetIndices [ fdx ] [ e ] ] ;
}
Centroid / = 3 ;
float Delta = ( Center - Centroid ) . Size ( ) ;
InnerRadius [ GeometryIndex ] = FMath : : Min ( InnerRadius [ GeometryIndex ] , Delta ) ;
OuterRadius [ GeometryIndex ] = FMath : : Max ( OuterRadius [ GeometryIndex ] , Delta ) ;
}
// Inner/Outer edges
for ( int fdx = IndicesStart ; fdx < IndicesStart + IndicesCount ; fdx + + )
{
for ( int e = 0 ; e < 3 ; e + + )
{
int i = e , j = ( e + 1 ) % 3 ;
FVector Edge = ( FVector ) TargetVertex [ TargetIndices [ fdx ] [ i ] ] + 0.5 * FVector ( TargetVertex [ TargetIndices [ fdx ] [ j ] ] - TargetVertex [ TargetIndices [ fdx ] [ i ] ] ) ;
float Delta = ( Center - Edge ) . Size ( ) ;
InnerRadius [ GeometryIndex ] = FMath : : Min ( InnerRadius [ GeometryIndex ] , Delta ) ;
OuterRadius [ GeometryIndex ] = FMath : : Max ( OuterRadius [ GeometryIndex ] , Delta ) ;
}
}
if ( ReindexMaterials ) {
GeometryCollection - > ReindexMaterials ( ) ;
}
# endif //WITH_EDITORONLY_DATA
}
FMeshDescription * FGeometryCollectionEngineConversion : : GetMaxResMeshDescriptionWithNormalsAndTangents ( const UStaticMesh * StaticMesh )
{
if ( StaticMesh = = nullptr )
{
return nullptr ;
}
2022-06-01 21:41:57 -04:00
FMeshDescription * MeshDescription = nullptr ;
2022-06-23 17:00:03 -04:00
# if WITH_EDITORONLY_DATA
// Prefer the HiRes description, although this isn't always available.
2022-06-01 21:41:57 -04:00
if ( StaticMesh - > IsHiResMeshDescriptionValid ( ) )
{
MeshDescription = StaticMesh - > GetHiResMeshDescription ( ) ;
}
else
{
MeshDescription = StaticMesh - > GetMeshDescription ( 0 ) ;
}
2022-06-23 17:00:03 -04:00
FStaticMeshOperations : : ComputeTriangleTangentsAndNormals ( * MeshDescription ) ;
FStaticMeshOperations : : RecomputeNormalsAndTangentsIfNeeded ( * MeshDescription , EComputeNTBsFlags : : UseMikkTSpace ) ;
# endif //WITH_EDITORONLY_DATA
return MeshDescription ;
}
2022-08-11 16:23:50 -04:00
int32 FGeometryCollectionEngineConversion : : AppendMaterials ( const TArray < UMaterialInterface * > & Materials , UGeometryCollection * GeometryCollectionObject , bool bAddInteriorCopy )
2022-06-23 17:00:03 -04:00
{
// for each material, add a reference in our GeometryCollectionObject
const int32 MaterialStart = GeometryCollectionObject - > Materials . Num ( ) ;
const int32 NumMeshMaterials = Materials . Num ( ) ;
GeometryCollectionObject - > Materials . Reserve ( MaterialStart + NumMeshMaterials ) ;
for ( int32 Index = 0 ; Index < NumMeshMaterials ; + + Index )
{
UMaterialInterface * CurrMaterial = Materials [ Index ] ;
// Possible we have a null entry - replace with default
if ( CurrMaterial = = nullptr )
{
CurrMaterial = UMaterial : : GetDefaultMaterial ( MD_Surface ) ;
}
// We add the material twice, once for interior and again for exterior.
GeometryCollectionObject - > Materials . Add ( CurrMaterial ) ;
2022-08-11 16:23:50 -04:00
if ( bAddInteriorCopy )
{
GeometryCollectionObject - > Materials . Add ( CurrMaterial ) ;
}
2022-06-23 17:00:03 -04:00
}
return MaterialStart ;
}
2022-08-18 15:37:22 -04:00
bool FGeometryCollectionEngineConversion : : AppendStaticMesh ( const UStaticMesh * StaticMesh , const TArray < UMaterialInterface * > & Materials ,
const FTransform & StaticMeshTransform , UGeometryCollection * GeometryCollectionObject , bool bReindexMaterials ,
bool bAddInternalMaterials , bool bSplitComponents )
2022-06-23 17:00:03 -04:00
{
# if WITH_EDITORONLY_DATA
int32 StartMaterialIndex = GeometryCollectionObject - > Materials . Num ( ) ;
2022-06-01 21:41:57 -04:00
check ( GeometryCollectionObject ) ;
TSharedPtr < FGeometryCollection , ESPMode : : ThreadSafe > GeometryCollectionPtr = GeometryCollectionObject - > GetGeometryCollection ( ) ;
FGeometryCollection * GeometryCollection = GeometryCollectionPtr . Get ( ) ;
check ( GeometryCollection ) ;
2022-08-18 15:37:22 -04:00
if ( AppendStaticMesh ( StaticMesh , StartMaterialIndex , StaticMeshTransform , GeometryCollection , bReindexMaterials , bAddInternalMaterials , bSplitComponents ) )
2022-06-23 17:00:03 -04:00
{
2022-08-18 15:37:22 -04:00
AppendMaterials ( Materials , GeometryCollectionObject , bAddInternalMaterials ) ;
2022-06-23 17:00:03 -04:00
return true ;
}
# endif //WITH_EDITORONLY_DATA
return false ;
}
2022-08-18 15:37:22 -04:00
bool FGeometryCollectionEngineConversion : : AppendStaticMesh ( const UStaticMesh * StaticMesh , int32 StartMaterialIndex , const FTransform & StaticMeshTransform ,
FGeometryCollection * GeometryCollection , bool bReindexMaterials , bool bAddInternalMaterials , bool bSplitComponents )
2022-06-23 17:00:03 -04:00
{
# if WITH_EDITORONLY_DATA
2022-06-24 12:28:07 -04:00
if ( StaticMesh )
2022-06-01 21:41:57 -04:00
{
2022-06-24 12:28:07 -04:00
FMeshDescription * MeshDescription = GetMaxResMeshDescriptionWithNormalsAndTangents ( StaticMesh ) ;
check ( GeometryCollection ) ;
if ( MeshDescription )
{
const FVector MeshBuildScale3D = GetMeshBuildScale3D ( * StaticMesh ) ;
const FTransform MeshTransform (
StaticMeshTransform . GetRotation ( ) ,
StaticMeshTransform . GetTranslation ( ) ,
StaticMeshTransform . GetScale3D ( ) * MeshBuildScale3D
) ;
2022-08-18 15:37:22 -04:00
if ( bSplitComponents )
{
int32 MaxVID = MeshDescription - > Vertices ( ) . Num ( ) ;
UE : : Geometry : : FVertexConnectedComponents Components ( MaxVID ) ;
for ( const FTriangleID TriangleID : MeshDescription - > Triangles ( ) . GetElementIDs ( ) )
{
TArrayView < const FVertexID > TriangleIDs = MeshDescription - > GetTriangleVertices ( TriangleID ) ;
Components . ConnectVertices ( TriangleIDs [ 0 ] . GetValue ( ) , TriangleIDs [ 1 ] . GetValue ( ) ) ;
Components . ConnectVertices ( TriangleIDs [ 1 ] . GetValue ( ) , TriangleIDs [ 2 ] . GetValue ( ) ) ;
}
if ( Components . HasMultipleComponents ( MaxVID , 2 ) )
{
// look up vertex positions
TVertexAttributesConstRef < FVector3f > VertexPositions = MeshDescription - > GetVertexPositions ( ) ;
// vertex instance attributes
FStaticMeshConstAttributes Attributes ( * MeshDescription ) ;
TVertexInstanceAttributesConstRef < FVector2f > InstanceUVs = Attributes . GetVertexInstanceUVs ( ) ;
TVertexInstanceAttributesConstRef < FVector3f > InstanceNormals = Attributes . GetVertexInstanceNormals ( ) ;
TVertexInstanceAttributesConstRef < FVector3f > InstanceTangents = Attributes . GetVertexInstanceTangents ( ) ;
TVertexInstanceAttributesConstRef < float > InstanceBiTangentSign = Attributes . GetVertexInstanceBinormalSigns ( ) ;
TVertexInstanceAttributesConstRef < FVector4f > InstanceColors = Attributes . GetVertexInstanceColors ( ) ;
const int NumUVLayers = InstanceUVs . GetNumChannels ( ) ;
TMap < int32 , int32 > Map = Components . MakeComponentMap ( MaxVID , 2 ) ;
int32 NumIslands = Map . Num ( ) ;
TArray < FMeshDescription > Descriptions ;
Descriptions . SetNum ( NumIslands ) ;
TArray < FMeshDescriptionBuilder > Builders ;
Builders . SetNum ( NumIslands ) ;
for ( int32 MeshIdx = 0 ; MeshIdx < NumIslands ; + + MeshIdx )
{
FStaticMeshAttributes MeshAttributes ( Descriptions [ MeshIdx ] ) ;
MeshAttributes . Register ( ) ;
Builders [ MeshIdx ] . SetMeshDescription ( & Descriptions [ MeshIdx ] ) ;
Builders [ MeshIdx ] . SuspendMeshDescriptionIndexing ( ) ;
Builders [ MeshIdx ] . SetNumUVLayers ( NumUVLayers ) ;
}
for ( TPair < int32 , int32 > IDToIdx : Map )
{
int32 ID = IDToIdx . Key ;
int32 Idx = IDToIdx . Value ;
int32 NumVertices = Components . GetComponentSize ( ID ) ;
Builders [ Idx ] . ReserveNewVertices ( NumVertices ) ;
}
TArray < int32 > VertexIDMap ;
VertexIDMap . Init ( INDEX_NONE , MeshDescription - > Vertices ( ) . Num ( ) ) ;
for ( const FVertexID VertexID : MeshDescription - > Vertices ( ) . GetElementIDs ( ) )
{
int32 MeshID = Components . GetComponent ( VertexID . GetValue ( ) ) ;
int32 * MeshIdx = Map . Find ( MeshID ) ;
if ( MeshIdx )
{
FVector Position = ( FVector ) VertexPositions . Get ( VertexID ) ;
VertexIDMap [ VertexID . GetValue ( ) ] = Builders [ * MeshIdx ] . AppendVertex ( Position ) ;
}
}
for ( const FTriangleID TriangleID : MeshDescription - > Triangles ( ) . GetElementIDs ( ) )
{
TArrayView < const FVertexID > TriangleVerts = MeshDescription - > GetTriangleVertices ( TriangleID ) ;
TArrayView < const FVertexInstanceID > SourceInstanceTri = MeshDescription - > GetTriangleVertexInstances ( TriangleID ) ;
int32 MeshID = Components . GetComponent ( TriangleVerts [ 0 ] . GetValue ( ) ) ;
int32 MeshIdx = Map [ MeshID ] ;
FMeshDescriptionBuilder & Builder = Builders [ MeshIdx ] ;
// create new vtx instances for each triangle
FVertexInstanceID DestInstanceTri [ 3 ] ;
for ( int32 j = 0 ; j < 3 ; + + j )
{
const FVertexID TriVertex = VertexIDMap [ TriangleVerts [ j ] . GetValue ( ) ] ;
DestInstanceTri [ j ] = Builder . AppendInstance ( TriVertex ) ;
}
// add the triangle to MeshDescription
FPolygonGroupID MaterialID = MeshDescription - > GetTrianglePolygonGroup ( TriangleID ) ;
FTriangleID NewTriangleID = Builder . AppendTriangle ( DestInstanceTri [ 0 ] , DestInstanceTri [ 1 ] , DestInstanceTri [ 2 ] , MaterialID ) ;
// transfer UVs. Note the Builder sets both the shared and per-instance UVs from this
for ( int32 UVLayer = 0 ; UVLayer < NumUVLayers ; + + UVLayer )
{
FUVID UVIDs [ 3 ] = { FUVID ( - 1 ) , FUVID ( - 1 ) , FUVID ( - 1 ) } ;
for ( int32 j = 0 ; j < 3 ; + + j )
{
FVector2D UV = ( FVector2D ) InstanceUVs . Get ( SourceInstanceTri [ j ] , UVLayer ) ;
UVIDs [ j ] = Builder . AppendUV ( UV , UVLayer ) ;
}
// append the UV triangle - builder takes care of the rest
Builder . AppendUVTriangle ( NewTriangleID , UVIDs [ 0 ] , UVIDs [ 1 ] , UVIDs [ 2 ] , UVLayer ) ;
}
// Set instance attributes: normal/tangent/bitangent frame and color
for ( int32 j = 0 ; j < 3 ; + + j )
{
const FVertexInstanceID SourceInstanceID = SourceInstanceTri [ j ] ;
const FVertexInstanceID DestInstanceID = DestInstanceTri [ j ] ;
FVector TriVertNormal = ( FVector ) InstanceNormals . Get ( SourceInstanceID ) ;
FVector TriVertTangent = ( FVector ) InstanceTangents . Get ( SourceInstanceID ) ;
float BiTangentSign = ( float ) InstanceBiTangentSign . Get ( SourceInstanceID ) ;
Builder . SetInstanceTangentSpace ( DestInstanceID , TriVertNormal , TriVertTangent , BiTangentSign ) ;
FVector4f InstColor = InstanceColors . Get ( SourceInstanceID ) ;
Builder . SetInstanceColor ( DestInstanceID , InstColor ) ;
}
}
for ( int32 MeshIdx = 0 ; MeshIdx < NumIslands ; + + MeshIdx )
{
Builders [ MeshIdx ] . ResumeMeshDescriptionIndexing ( ) ;
}
for ( FMeshDescription & MD : Descriptions )
{
AppendMeshDescription ( & MD , StaticMesh - > GetName ( ) , StartMaterialIndex , MeshTransform , GeometryCollection , StaticMesh - > GetBodySetup ( ) , false , bAddInternalMaterials ) ;
}
if ( bReindexMaterials )
{
GeometryCollection - > ReindexMaterials ( ) ;
}
return true ;
}
// else only one component -- fall back to just using the original mesh description
}
AppendMeshDescription ( MeshDescription , StaticMesh - > GetName ( ) , StartMaterialIndex , MeshTransform , GeometryCollection , StaticMesh - > GetBodySetup ( ) , bReindexMaterials , bAddInternalMaterials ) ;
2022-06-24 12:28:07 -04:00
return true ;
}
2022-06-01 21:41:57 -04:00
}
# endif //WITH_EDITORONLY_DATA
2022-06-23 17:00:03 -04:00
return false ;
2022-06-01 21:41:57 -04:00
}
2022-06-23 17:00:03 -04:00
bool FGeometryCollectionEngineConversion : : AppendGeometryCollection ( const FGeometryCollection * SourceGeometryCollectionPtr , int32 AssetMaterialStart , const FTransform & GeometryCollectionTransform , FGeometryCollection * TargetGeometryCollection , bool bReindexMaterials )
{
if ( SourceGeometryCollectionPtr = = nullptr )
{
return false ;
}
2022-06-01 21:41:57 -04:00
// Assemble offsets and add elements
const int32 VertexCount = SourceGeometryCollectionPtr - > Vertex . Num ( ) ;
const int32 FaceCount = SourceGeometryCollectionPtr - > Indices . Num ( ) ;
const int32 TransformCount = SourceGeometryCollectionPtr - > Transform . Num ( ) ;
const int32 GeometryCount = SourceGeometryCollectionPtr - > TransformIndex . Num ( ) ;
const int32 SectionCount = SourceGeometryCollectionPtr - > Sections . Num ( ) ;
FVector Scale = GeometryCollectionTransform . GetScale3D ( ) ;
FTransform AppliedTransform = GeometryCollectionTransform ;
AppliedTransform . RemoveScaling ( ) ;
2022-06-23 17:00:03 -04:00
const int32 VertexStart = TargetGeometryCollection - > AddElements ( VertexCount , FGeometryCollection : : VerticesGroup ) ;
const int32 FaceStart = TargetGeometryCollection - > AddElements ( FaceCount , FGeometryCollection : : FacesGroup ) ;
const int32 TransformStart = TargetGeometryCollection - > AddElements ( TransformCount , FGeometryCollection : : TransformGroup ) ;
const int32 GeometryStart = TargetGeometryCollection - > AddElements ( GeometryCount , FGeometryCollection : : GeometryGroup ) ;
const int32 SectionStart = TargetGeometryCollection - > AddElements ( SectionCount , FGeometryCollection : : MaterialGroup ) ;
2022-06-01 21:41:57 -04:00
// source vertex information
const TManagedArray < FVector3f > & SourceVertex = SourceGeometryCollectionPtr - > Vertex ;
const TManagedArray < FVector3f > & SourceTangentU = SourceGeometryCollectionPtr - > TangentU ;
const TManagedArray < FVector3f > & SourceTangentV = SourceGeometryCollectionPtr - > TangentV ;
const TManagedArray < FVector3f > & SourceNormal = SourceGeometryCollectionPtr - > Normal ;
const TManagedArray < TArray < FVector2f > > & SourceUVs = SourceGeometryCollectionPtr - > UVs ;
const TManagedArray < FLinearColor > & SourceColor = SourceGeometryCollectionPtr - > Color ;
const TManagedArray < int32 > & SourceBoneMap = SourceGeometryCollectionPtr - > BoneMap ;
// target vertex information
2022-06-23 17:00:03 -04:00
TManagedArray < FVector3f > & TargetVertex = TargetGeometryCollection - > Vertex ;
TManagedArray < FVector3f > & TargetTangentU = TargetGeometryCollection - > TangentU ;
TManagedArray < FVector3f > & TargetTangentV = TargetGeometryCollection - > TangentV ;
TManagedArray < FVector3f > & TargetNormal = TargetGeometryCollection - > Normal ;
TManagedArray < TArray < FVector2f > > & TargetUVs = TargetGeometryCollection - > UVs ;
TManagedArray < FLinearColor > & TargetColor = TargetGeometryCollection - > Color ;
TManagedArray < int32 > & TargetBoneMap = TargetGeometryCollection - > BoneMap ;
2022-06-01 21:41:57 -04:00
// append vertices
for ( int32 VertexIndex = 0 ; VertexIndex < VertexCount ; VertexIndex + + )
{
const int32 VertexOffset = VertexStart + VertexIndex ;
TargetVertex [ VertexOffset ] = SourceVertex [ VertexIndex ] * ( FVector3f ) Scale ;
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
TargetTangentU [ VertexOffset ] = SourceTangentU [ VertexIndex ] ;
TargetTangentV [ VertexOffset ] = SourceTangentV [ VertexIndex ] ;
TargetNormal [ VertexOffset ] = SourceNormal [ VertexIndex ] ;
TargetUVs [ VertexOffset ] = SourceUVs [ VertexIndex ] ;
TargetColor [ VertexOffset ] = SourceColor [ VertexIndex ] ;
TargetBoneMap [ VertexOffset ] = SourceBoneMap [ VertexIndex ] + TransformStart ;
}
// source face information
const TManagedArray < FIntVector > & SourceIndices = SourceGeometryCollectionPtr - > Indices ;
const TManagedArray < bool > & SourceVisible = SourceGeometryCollectionPtr - > Visible ;
const TManagedArray < int32 > & SourceMaterialID = SourceGeometryCollectionPtr - > MaterialID ;
const TManagedArray < int32 > & SourceMaterialIndex = SourceGeometryCollectionPtr - > MaterialIndex ;
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
// target face information
2022-06-23 17:00:03 -04:00
TManagedArray < FIntVector > & TargetIndices = TargetGeometryCollection - > Indices ;
TManagedArray < bool > & TargetVisible = TargetGeometryCollection - > Visible ;
TManagedArray < int32 > & TargetMaterialID = TargetGeometryCollection - > MaterialID ;
TManagedArray < int32 > & TargetMaterialIndex = TargetGeometryCollection - > MaterialIndex ;
2022-06-01 21:41:57 -04:00
// append faces
for ( int32 FaceIndex = 0 ; FaceIndex < FaceCount ; + + FaceIndex )
{
const FIntVector & SourceFace = SourceIndices [ FaceIndex ] ;
const int32 FaceOffset = FaceStart + FaceIndex ;
TargetIndices [ FaceOffset ] = FIntVector (
SourceFace [ 0 ] + VertexStart ,
SourceFace [ 1 ] + VertexStart ,
SourceFace [ 2 ] + VertexStart ) ;
TargetVisible [ FaceOffset ] = SourceVisible [ FaceIndex ] ;
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
TargetMaterialID [ FaceOffset ] = AssetMaterialStart + SourceMaterialID [ FaceIndex ] ;
TargetMaterialIndex [ FaceOffset ] = FaceOffset ;
}
2022-06-03 23:13:28 -04:00
using FCollisionType = FGeometryDynamicCollection : : FSharedImplicit ;
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
// source transform information
const TManagedArray < FTransform > & SourceTransform = SourceGeometryCollectionPtr - > Transform ;
const TManagedArray < FString > & SourceBoneName = SourceGeometryCollectionPtr - > BoneName ;
const TManagedArray < FLinearColor > & SourceBoneColor = SourceGeometryCollectionPtr - > BoneColor ;
const TManagedArray < int32 > & SourceParent = SourceGeometryCollectionPtr - > Parent ;
const TManagedArray < TSet < int32 > > & SourceChildren = SourceGeometryCollectionPtr - > Children ;
const TManagedArray < int32 > & SourceTransformToGeometryIndex = SourceGeometryCollectionPtr - > TransformToGeometryIndex ;
const TManagedArray < int32 > & SourceSimulationType = SourceGeometryCollectionPtr - > SimulationType ;
const TManagedArray < int32 > & SourceStatusFlags = SourceGeometryCollectionPtr - > StatusFlags ;
const TManagedArray < int32 > & SourceInitialDynamicState = SourceGeometryCollectionPtr - > InitialDynamicState ;
2022-06-03 23:13:28 -04:00
const TManagedArray < FCollisionType > * SourceExternalCollisions = SourceGeometryCollectionPtr - > FindAttribute < FCollisionType > ( " ExternalCollisions " , FGeometryCollection : : TransformGroup ) ;
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
// target transform information
2022-06-23 17:00:03 -04:00
TManagedArray < FTransform > & TargetTransform = TargetGeometryCollection - > Transform ;
TManagedArray < FString > & TargetBoneName = TargetGeometryCollection - > BoneName ;
TManagedArray < FLinearColor > & TargetBoneColor = TargetGeometryCollection - > BoneColor ;
TManagedArray < int32 > & TargetParent = TargetGeometryCollection - > Parent ;
TManagedArray < TSet < int32 > > & TargetChildren = TargetGeometryCollection - > Children ;
TManagedArray < int32 > & TargetTransformToGeometryIndex = TargetGeometryCollection - > TransformToGeometryIndex ;
TManagedArray < int32 > & TargetSimulationType = TargetGeometryCollection - > SimulationType ;
TManagedArray < int32 > & TargetStatusFlags = TargetGeometryCollection - > StatusFlags ;
TManagedArray < int32 > & TargetInitialDynamicState = TargetGeometryCollection - > InitialDynamicState ;
TManagedArray < FCollisionType > & TargetExternalCollisions = TargetGeometryCollection - > AddAttribute < FCollisionType > ( " ExternalCollisions " , FGeometryCollection : : TransformGroup ) ;
2022-06-01 21:41:57 -04:00
// append transform hierarchy
for ( int32 TransformIndex = 0 ; TransformIndex < TransformCount ; + + TransformIndex )
{
const int32 TransformOffset = TransformStart + TransformIndex ;
// Only apply the transform to the parent node. Child nodes only need scaling applied to translation offsets.
if ( SourceParent [ TransformIndex ] = = INDEX_NONE )
{
TargetTransform [ TransformOffset ] = SourceTransform [ TransformIndex ] * AppliedTransform ;
}
else
{
FTransform ScaledTranslation = SourceTransform [ TransformIndex ] ;
ScaledTranslation . ScaleTranslation ( Scale ) ;
TargetTransform [ TransformOffset ] = ScaledTranslation ;
}
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
// #todo Get this Bone name to be unique
TargetBoneName [ TransformOffset ] = SourceBoneName [ TransformIndex ] ;
const FColor RandBoneColor ( FMath : : Rand ( ) % 100 + 5 , FMath : : Rand ( ) % 100 + 5 , FMath : : Rand ( ) % 100 + 5 , 255 ) ;
TargetBoneColor [ TransformOffset ] = FLinearColor ( RandBoneColor ) ;
2022-06-23 17:00:03 -04:00
TargetParent [ TransformOffset ] = ( SourceParent [ TransformIndex ] = = INDEX_NONE ) ? INDEX_NONE : SourceParent [ TransformIndex ] + TransformStart ;
2022-06-01 21:41:57 -04:00
const TSet < int32 > & SourceChildrenSet = SourceChildren [ TransformIndex ] ;
for ( int32 ChildIndex : SourceChildrenSet )
{
TargetChildren [ TransformOffset ] . Add ( ChildIndex + TransformStart ) ;
}
TargetTransformToGeometryIndex [ TransformOffset ] = SourceTransformToGeometryIndex [ TransformIndex ] + GeometryStart ;
TargetSimulationType [ TransformOffset ] = SourceSimulationType [ TransformIndex ] ;
TargetStatusFlags [ TransformOffset ] = SourceStatusFlags [ TransformIndex ] ;
TargetInitialDynamicState [ TransformOffset ] = SourceInitialDynamicState [ TransformIndex ] ;
2022-06-03 23:13:28 -04:00
TargetExternalCollisions [ TransformOffset ] = nullptr ;
if ( SourceExternalCollisions )
{
TargetExternalCollisions [ TransformOffset ] = ( * SourceExternalCollisions ) [ TransformIndex ] ;
}
2022-06-01 21:41:57 -04:00
}
// source geometry information
const TManagedArray < int32 > & SourceTransformIndex = SourceGeometryCollectionPtr - > TransformIndex ;
const TManagedArray < int32 > & SourceVertexStart = SourceGeometryCollectionPtr - > VertexStart ;
const TManagedArray < int32 > & SourceVertexCount = SourceGeometryCollectionPtr - > VertexCount ;
const TManagedArray < int32 > & SourceFaceStart = SourceGeometryCollectionPtr - > FaceStart ;
const TManagedArray < int32 > & SourceFaceCount = SourceGeometryCollectionPtr - > FaceCount ;
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
// target geometry information
2022-06-23 17:00:03 -04:00
TManagedArray < int32 > & TargetTransformIndex = TargetGeometryCollection - > TransformIndex ;
TManagedArray < FBox > & TargetBoundingBox = TargetGeometryCollection - > BoundingBox ;
TManagedArray < float > & TargetInnerRadius = TargetGeometryCollection - > InnerRadius ;
TManagedArray < float > & TargetOuterRadius = TargetGeometryCollection - > OuterRadius ;
TManagedArray < int32 > & TargetVertexStart = TargetGeometryCollection - > VertexStart ;
TManagedArray < int32 > & TargetVertexCount = TargetGeometryCollection - > VertexCount ;
TManagedArray < int32 > & TargetFaceStart = TargetGeometryCollection - > FaceStart ;
TManagedArray < int32 > & TargetFaceCount = TargetGeometryCollection - > FaceCount ;
2022-06-01 21:41:57 -04:00
// append geometry
for ( int32 GeometryIndex = 0 ; GeometryIndex < GeometryCount ; + + GeometryIndex )
{
const int32 GeometryOffset = GeometryStart + GeometryIndex ;
TargetTransformIndex [ GeometryOffset ] = SourceTransformIndex [ GeometryIndex ] + TransformStart ;
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
TargetVertexStart [ GeometryOffset ] = SourceVertexStart [ GeometryIndex ] + VertexStart ;
TargetVertexCount [ GeometryOffset ] = SourceVertexCount [ GeometryIndex ] ;
TargetFaceStart [ GeometryOffset ] = SourceFaceStart [ GeometryIndex ] + FaceStart ;
TargetFaceCount [ GeometryOffset ] = SourceFaceCount [ GeometryIndex ] ;
// Find centroid of geometry for inner/outer radius calculations
FVector Center ( 0 ) ;
for ( int32 VertexIndex = TargetVertexStart [ GeometryOffset ] ; VertexIndex < TargetVertexStart [ GeometryOffset ] + TargetVertexCount [ GeometryOffset ] ; + + VertexIndex )
{
Center + = ( FVector ) TargetVertex [ VertexIndex ] ;
}
if ( TargetVertexCount [ GeometryOffset ] ) Center / = TargetVertexCount [ GeometryOffset ] ;
2022-06-23 17:00:03 -04:00
2022-06-01 21:41:57 -04:00
TargetBoundingBox [ GeometryOffset ] = FBox ( ForceInitToZero ) ;
TargetInnerRadius [ GeometryOffset ] = FLT_MAX ;
TargetOuterRadius [ GeometryOffset ] = - FLT_MAX ;
for ( int32 VertexIndex = TargetVertexStart [ GeometryOffset ] ; VertexIndex < TargetVertexStart [ GeometryOffset ] + TargetVertexCount [ GeometryOffset ] ; + + VertexIndex )
{
TargetBoundingBox [ GeometryOffset ] + = ( FVector ) TargetVertex [ VertexIndex ] ;
float Delta = ( Center - ( FVector ) TargetVertex [ VertexIndex ] ) . Size ( ) ;
TargetInnerRadius [ GeometryOffset ] = FMath : : Min ( TargetInnerRadius [ GeometryOffset ] , Delta ) ;
TargetOuterRadius [ GeometryOffset ] = FMath : : Max ( TargetOuterRadius [ GeometryOffset ] , Delta ) ;
}
}
// source material information
const TManagedArray < FGeometryCollectionSection > & SourceSections = SourceGeometryCollectionPtr - > Sections ;
// target material information
2022-06-23 17:00:03 -04:00
TManagedArray < FGeometryCollectionSection > & TargetSections = TargetGeometryCollection - > Sections ;
2022-06-01 21:41:57 -04:00
// append sections
for ( int32 SectionIndex = 0 ; SectionIndex < SectionCount ; + + SectionIndex )
{
int32 SectionOffset = SectionStart + SectionIndex ;
TargetSections [ SectionOffset ] . MaterialID = AssetMaterialStart + SourceSections [ SectionIndex ] . MaterialID ;
TargetSections [ SectionOffset ] . FirstIndex = SourceSections [ SectionIndex ] . FirstIndex + FaceStart * 3 ;
TargetSections [ SectionOffset ] . MinVertexIndex = VertexStart + SourceSections [ SectionIndex ] . MinVertexIndex ;
TargetSections [ SectionOffset ] . NumTriangles = SourceSections [ SectionIndex ] . NumTriangles ;
TargetSections [ SectionOffset ] . MaxVertexIndex = VertexStart + SourceSections [ SectionIndex ] . MaxVertexIndex ;
}
2022-06-23 17:00:03 -04:00
if ( bReindexMaterials )
{
TargetGeometryCollection - > ReindexMaterials ( ) ;
2022-06-01 21:41:57 -04:00
}
2022-06-23 17:00:03 -04:00
return true ;
}
void FGeometryCollectionEngineConversion : : AppendGeometryCollection ( const UGeometryCollection * SourceGeometryCollection , const TArray < UMaterialInterface * > & Materials , const FTransform & GeometryCollectionTransform , UGeometryCollection * TargetGeometryCollectionObject , bool bReindexMaterials )
{
if ( SourceGeometryCollection = = nullptr )
{
return ;
}
const TSharedPtr < FGeometryCollection , ESPMode : : ThreadSafe > SourceGeometryCollectionPtr = SourceGeometryCollection - > GetGeometryCollection ( ) ;
check ( TargetGeometryCollectionObject ) ;
TSharedPtr < FGeometryCollection , ESPMode : : ThreadSafe > GeometryCollectionPtr = TargetGeometryCollectionObject - > GetGeometryCollection ( ) ;
FGeometryCollection * GeometryCollection = GeometryCollectionPtr . Get ( ) ;
check ( GeometryCollection ) ;
2022-08-11 16:23:50 -04:00
int32 MaterialStart = AppendMaterials ( Materials , TargetGeometryCollectionObject , false ) ;
2022-06-23 17:00:03 -04:00
AppendGeometryCollection ( SourceGeometryCollectionPtr . Get ( ) , MaterialStart , GeometryCollectionTransform , GeometryCollection , bReindexMaterials ) ;
2022-06-01 21:41:57 -04:00
}
2022-08-18 15:37:22 -04:00
void FGeometryCollectionEngineConversion : : AppendStaticMesh ( const UStaticMesh * StaticMesh , const UStaticMeshComponent * StaticMeshComponent , const FTransform & StaticMeshTransform , UGeometryCollection * GeometryCollectionObject ,
bool ReindexMaterials , bool bAddInternalMaterials , bool bSplitComponents )
2022-06-01 21:41:57 -04:00
{
if ( StaticMesh = = nullptr )
{
return ;
}
TArray < UMaterialInterface * > Materials ;
Materials . Reserve ( StaticMesh - > GetStaticMaterials ( ) . Num ( ) ) ;
for ( int32 Index = 0 ; Index < StaticMesh - > GetStaticMaterials ( ) . Num ( ) ; + + Index )
{
UMaterialInterface * CurrMaterial = StaticMeshComponent ? StaticMeshComponent - > GetMaterial ( Index ) : StaticMesh - > GetMaterial ( Index ) ;
Materials . Add ( CurrMaterial ) ;
}
// Geometry collections usually carry the selection material, which we'll delete before appending
UMaterialInterface * BoneSelectedMaterial = LoadObject < UMaterialInterface > ( nullptr , UGeometryCollection : : GetSelectedMaterialPath ( ) , nullptr , LOAD_None , nullptr ) ;
GeometryCollectionObject - > Materials . Remove ( BoneSelectedMaterial ) ;
Materials . Remove ( BoneSelectedMaterial ) ;
2022-08-18 15:37:22 -04:00
AppendStaticMesh ( StaticMesh , Materials , StaticMeshTransform , GeometryCollectionObject , ReindexMaterials , bAddInternalMaterials , bSplitComponents ) ;
2022-06-01 21:41:57 -04:00
}
2022-06-23 17:00:03 -04:00
int32 FGeometryCollectionEngineConversion : : AppendGeometryCollectionMaterials ( const UGeometryCollection * SourceGeometryCollection , const UGeometryCollectionComponent * GeometryCollectionComponent , UGeometryCollection * TargetGeometryCollectionObject )
2022-06-01 21:41:57 -04:00
{
2022-06-23 17:00:03 -04:00
check ( SourceGeometryCollection ) ;
check ( GeometryCollectionComponent ) ;
check ( TargetGeometryCollectionObject ) ;
2022-06-01 21:41:57 -04:00
TArray < UMaterialInterface * > Materials ;
Materials . Reserve ( SourceGeometryCollection - > Materials . Num ( ) ) ;
for ( int32 Index = 0 ; Index < SourceGeometryCollection - > Materials . Num ( ) ; + + Index )
{
UMaterialInterface * CurrMaterial = GeometryCollectionComponent ? GeometryCollectionComponent - > GetMaterial ( Index ) : SourceGeometryCollection - > Materials [ Index ] . Get ( ) ;
Materials . Add ( CurrMaterial ) ;
}
// Geometry collections usually carry the selection material, which we'll delete before appending
UMaterialInterface * BoneSelectedMaterial = LoadObject < UMaterialInterface > ( nullptr , UGeometryCollection : : GetSelectedMaterialPath ( ) , nullptr , LOAD_None , nullptr ) ;
TargetGeometryCollectionObject - > Materials . Remove ( BoneSelectedMaterial ) ;
Materials . Remove ( BoneSelectedMaterial ) ;
2022-08-11 16:23:50 -04:00
return AppendMaterials ( Materials , TargetGeometryCollectionObject , false ) ;
2022-06-01 21:41:57 -04:00
}
2022-06-23 17:00:03 -04:00
void FGeometryCollectionEngineConversion : : AppendGeometryCollection ( const UGeometryCollection * SourceGeometryCollection , const UGeometryCollectionComponent * GeometryCollectionComponent , const FTransform & GeometryCollectionTransform , UGeometryCollection * TargetGeometryCollectionObject , bool bReindexMaterials )
{
if ( SourceGeometryCollection = = nullptr )
{
return ;
}
int32 MaterialStartIndex = AppendGeometryCollectionMaterials ( SourceGeometryCollection , GeometryCollectionComponent , TargetGeometryCollectionObject ) ;
const TSharedPtr < FGeometryCollection , ESPMode : : ThreadSafe > SourceGeometryCollectionPtr = SourceGeometryCollection - > GetGeometryCollection ( ) ;
check ( TargetGeometryCollectionObject ) ;
TSharedPtr < FGeometryCollection , ESPMode : : ThreadSafe > GeometryCollectionPtr = TargetGeometryCollectionObject - > GetGeometryCollection ( ) ;
FGeometryCollection * GeometryCollection = GeometryCollectionPtr . Get ( ) ;
check ( GeometryCollection ) ;
AppendGeometryCollection ( SourceGeometryCollectionPtr . Get ( ) , MaterialStartIndex , GeometryCollectionTransform , GeometryCollection , bReindexMaterials ) ;
}
2022-09-16 19:43:53 -04:00
bool FGeometryCollectionEngineConversion : : AppendSkeletalMesh ( const USkeletalMesh * SkeletalMesh , int32 MaterialStartIndex , const FTransform & SkeletalMeshTransform , FManagedArrayCollection * InCollection , bool bReindexMaterials )
2022-06-23 17:00:03 -04:00
{
//UE_LOG(UGeometryCollectionConversionLogging, Log, TEXT("FGeometryCollectionEngineConversion::AppendSkeletalMesh()"));
2022-09-16 19:43:53 -04:00
if ( ! InCollection )
2022-06-23 17:00:03 -04:00
{
return false ;
}
2022-09-21 11:19:57 -04:00
FGeometryCollection : : DefineGeometrySchema ( * InCollection ) ;
2022-06-23 17:00:03 -04:00
const FSkeletalMeshLODRenderData * MeshLODData = GetSkeletalMeshLOD ( SkeletalMesh , 0 ) ;
if ( ! MeshLODData )
{
return false ;
}
const FSkeletalMeshLODRenderData & SkeletalMeshLODRenderData = * MeshLODData ;
const FSkinWeightVertexBuffer & SkinWeightVertexBuffer = * SkeletalMeshLODRenderData . GetSkinWeightVertexBuffer ( ) ;
const FStaticMeshVertexBuffers & VertexBuffers = SkeletalMeshLODRenderData . StaticVertexBuffers ;
const FPositionVertexBuffer & PositionVertexBuffer = VertexBuffers . PositionVertexBuffer ;
const int32 VertexCount = PositionVertexBuffer . GetNumVertices ( ) ;
// Check that all vertex weightings are rigid.
for ( int32 VertexIndex = 0 ; VertexIndex < VertexCount ; VertexIndex + + )
{
int32 SkeletalBoneIndex = - 1 ;
if ( ! SkinWeightVertexBuffer . GetRigidWeightBone ( VertexIndex , SkeletalBoneIndex ) )
{
UE_LOG ( UGeometryCollectionConversionLogging , Error , TEXT ( " Non-rigid weighting found on vertex %d: Cannot convert to GeometryCollection. " ) , VertexIndex ) ;
return false ;
}
}
const FSkelMeshRenderSection & RenderSection = SkeletalMeshLODRenderData . RenderSections [ 0 ] ;
const TArray < FBoneIndexType > & SkeletalBoneMap = RenderSection . BoneMap ;
//
// The Component transform for each Mesh will become the FTransform that drives
// its associated VerticesGroup. The Skeleton will contain a nested transform hierarchy
// that is evaluated using the GetComponentSpaceTransformRefPose. The resulting
// Transforms array stored in the GeometryCollection will be the same size as
// the SkeletalBoneMap. Note the @todo: the SkeletalBoneMap is pulled from only
// the first render section, this will need to be expanded to include all render
// sections.
//
const USkeleton * Skeleton = SkeletalMesh - > GetSkeleton ( ) ;
2022-09-16 19:43:53 -04:00
TManagedArray < FTransform > & Transform = InCollection - > ModifyAttribute < FTransform > ( FTransformCollection : : TransformAttribute , FTransformCollection : : TransformGroup ) ;
int32 TransformBaseIndex = InCollection - > AddElements ( SkeletalBoneMap . Num ( ) , FGeometryCollection : : TransformGroup ) ;
2022-06-23 17:00:03 -04:00
const FReferenceSkeleton & ReferenceSkeletion = Skeleton - > GetReferenceSkeleton ( ) ;
const TArray < FTransform > & RestArray = Skeleton - > GetRefLocalPoses ( ) ;
for ( int32 BoneIndex = 0 ; BoneIndex < SkeletalBoneMap . Num ( ) ; BoneIndex + + )
{
FTransform BoneTransform = FAnimationRuntime : : GetComponentSpaceTransformRefPose ( ReferenceSkeletion , SkeletalBoneMap [ BoneIndex ] ) ;
Transform [ TransformBaseIndex + BoneIndex ] = BoneTransform ;
}
//
// The Triangle Indices
//
2022-09-16 19:43:53 -04:00
TManagedArray < FIntVector > & Indices = InCollection - > ModifyAttribute < FIntVector > ( " Indices " , FGeometryCollection : : FacesGroup ) ;
TManagedArray < bool > & Visible = InCollection - > ModifyAttribute < bool > ( " Visible " , FGeometryCollection : : FacesGroup ) ;
TManagedArray < int32 > & MaterialIndex = InCollection - > ModifyAttribute < int32 > ( " MaterialIndex " , FGeometryCollection : : FacesGroup ) ;
TManagedArray < int32 > & MaterialID = InCollection - > ModifyAttribute < int32 > ( " MaterialID " , FGeometryCollection : : FacesGroup ) ;
2022-06-23 17:00:03 -04:00
TArray < uint32 > IndexBuffer ;
SkeletalMeshLODRenderData . MultiSizeIndexContainer . GetIndexBuffer ( IndexBuffer ) ;
const int32 IndicesCount = IndexBuffer . Num ( ) / 3 ;
2022-09-16 19:43:53 -04:00
int NumVertices = InCollection - > NumElements ( FGeometryCollection : : VerticesGroup ) ;
int InitialNumIndices = InCollection - > NumElements ( FGeometryCollection : : FacesGroup ) ;
int IndicesBaseIndex = InCollection - > AddElements ( IndicesCount , FGeometryCollection : : FacesGroup ) ;
2022-06-23 17:00:03 -04:00
for ( int32 IndicesIndex = 0 , StaticIndex = 0 ; IndicesIndex < IndicesCount ; IndicesIndex + + , StaticIndex + = 3 )
{
int32 IndicesOffset = IndicesBaseIndex + IndicesIndex ;
Indices [ IndicesOffset ] = FIntVector (
IndexBuffer [ StaticIndex ] + NumVertices ,
IndexBuffer [ StaticIndex + 1 ] + NumVertices ,
IndexBuffer [ StaticIndex + 2 ] + NumVertices ) ;
Visible [ IndicesOffset ] = true ;
MaterialID [ IndicesOffset ] = 0 ;
MaterialIndex [ IndicesOffset ] = IndicesOffset ;
}
//
// Vertex Attributes
//
2022-09-16 19:43:53 -04:00
TManagedArray < FVector3f > & Vertex = InCollection - > ModifyAttribute < FVector3f > ( " Vertex " , FGeometryCollection : : VerticesGroup ) ;
TManagedArray < FVector3f > & Normal = InCollection - > ModifyAttribute < FVector3f > ( " Normal " , FGeometryCollection : : VerticesGroup ) ;
TManagedArray < TArray < FVector2f > > & UVs = InCollection - > ModifyAttribute < TArray < FVector2f > > ( " UVs " , FGeometryCollection : : VerticesGroup ) ;
TManagedArray < FLinearColor > & Color = InCollection - > ModifyAttribute < FLinearColor > ( " Color " , FGeometryCollection : : VerticesGroup ) ;
TManagedArray < FVector3f > & TangentU = InCollection - > ModifyAttribute < FVector3f > ( " TangentU " , FGeometryCollection : : VerticesGroup ) ;
TManagedArray < FVector3f > & TangentV = InCollection - > ModifyAttribute < FVector3f > ( " TangentV " , FGeometryCollection : : VerticesGroup ) ;
TManagedArray < int32 > & BoneMap = InCollection - > ModifyAttribute < int32 > ( " BoneMap " , FGeometryCollection : : VerticesGroup ) ;
TManagedArray < FLinearColor > & BoneColor = InCollection - > ModifyAttribute < FLinearColor > ( " BoneColor " , FTransformCollection : : TransformGroup ) ;
TManagedArray < FString > & BoneName = InCollection - > ModifyAttribute < FString > ( " BoneName " , FTransformCollection : : TransformGroup ) ;
2022-06-23 17:00:03 -04:00
//
// Transform Attributes
//
2022-09-16 19:43:53 -04:00
TManagedArray < int32 > & Parent = InCollection - > ModifyAttribute < int32 > ( FTransformCollection : : ParentAttribute , FTransformCollection : : TransformGroup ) ;
TManagedArray < int32 > & SimulationType = InCollection - > ModifyAttribute < int32 > ( " SimulationType " , FTransformCollection : : TransformGroup ) ;
int InitialNumVertices = InCollection - > NumElements ( FGeometryCollection : : VerticesGroup ) ;
int VertexBaseIndex = InCollection - > AddElements ( VertexCount , FGeometryCollection : : VerticesGroup ) ;
2022-06-23 17:00:03 -04:00
const int32 NumUVLayers = VertexBuffers . StaticMeshVertexBuffer . GetNumTexCoords ( ) ;
for ( int32 VertexIndex = 0 ; VertexIndex < VertexCount ; VertexIndex + + )
{
int VertexOffset = VertexBaseIndex + VertexIndex ;
BoneMap [ VertexOffset ] = - 1 ;
int32 SkeletalBoneIndex = - 1 ;
SkinWeightVertexBuffer . GetRigidWeightBone ( VertexIndex , SkeletalBoneIndex ) ;
if ( SkeletalBoneIndex > - 1 )
{
BoneMap [ VertexOffset ] = SkeletalBoneIndex + TransformBaseIndex ;
Vertex [ VertexOffset ] = ( FVector4f ) Transform [ BoneMap [ VertexOffset ] ] . ToInverseMatrixWithScale ( ) . TransformPosition ( ( FVector ) PositionVertexBuffer . VertexPosition ( VertexIndex ) ) ;
}
check ( BoneMap [ VertexOffset ] ! = - 1 ) ;
TangentU [ VertexOffset ] = VertexBuffers . StaticMeshVertexBuffer . VertexTangentX ( VertexIndex ) ;
TangentV [ VertexOffset ] = VertexBuffers . StaticMeshVertexBuffer . VertexTangentY ( VertexIndex ) ;
Normal [ VertexOffset ] = VertexBuffers . StaticMeshVertexBuffer . VertexTangentZ ( VertexIndex ) ;
2022-09-16 19:43:53 -04:00
2022-06-23 17:00:03 -04:00
UVs [ VertexOffset ] . SetNum ( NumUVLayers ) ;
for ( int32 UVLayerIdx = 0 ; UVLayerIdx < NumUVLayers ; + + UVLayerIdx )
{
UVs [ VertexOffset ] [ UVLayerIdx ] = VertexBuffers . StaticMeshVertexBuffer . GetVertexUV ( VertexIndex , UVLayerIdx ) ;
}
2022-09-16 19:43:53 -04:00
2022-06-23 17:00:03 -04:00
if ( VertexBuffers . ColorVertexBuffer . GetNumVertices ( ) = = VertexCount )
Color [ VertexOffset ] = VertexBuffers . ColorVertexBuffer . VertexColor ( VertexIndex ) ;
else
Color [ VertexOffset ] = FLinearColor : : White ;
}
int32 InitialIndex = - 1 ;
int32 LastParentIndex = - 1 ;
int32 CurrentLevel = 0 ;
for ( int32 BoneIndex = 0 ; BoneIndex < SkeletalBoneMap . Num ( ) ; BoneIndex + + )
{
// transform based on position of the actor.
Transform [ TransformBaseIndex + BoneIndex ] = SkeletalMeshTransform * Transform [ TransformBaseIndex + BoneIndex ] ;
// bone attributes
BoneName [ TransformBaseIndex + BoneIndex ] = ReferenceSkeletion . GetBoneName ( SkeletalBoneMap [ BoneIndex ] ) . ToString ( ) ;
const FColor RandBoneColor ( FMath : : Rand ( ) % 100 + 5 , FMath : : Rand ( ) % 100 + 5 , FMath : : Rand ( ) % 100 + 5 , 255 ) ;
BoneColor [ TransformBaseIndex + BoneIndex ] = FLinearColor ( RandBoneColor ) ;
// Bone Hierarchy - Added at root with no common parent
int32 ParentIndex = ReferenceSkeletion . GetParentIndex ( SkeletalBoneMap [ BoneIndex ] ) ;
int32 UseParentIndex = ParentIndex + InitialIndex ;
if ( LastParentIndex ! = UseParentIndex )
{
LastParentIndex = UseParentIndex ;
}
Parent [ TransformBaseIndex + BoneIndex ] = UseParentIndex ;
SimulationType [ TransformBaseIndex + BoneIndex ] = FGeometryCollection : : ESimulationTypes : : FST_Rigid ;
}
// Geometry Group
TArray < int32 > GeometryIndices ;
2022-09-16 19:43:53 -04:00
GeometryCollectionAlgo : : ContiguousArray ( GeometryIndices , InCollection - > NumElements ( FGeometryCollection : : GeometryGroup ) ) ;
InCollection - > RemoveDependencyFor ( FGeometryCollection : : GeometryGroup ) ;
InCollection - > RemoveElements ( FGeometryCollection : : GeometryGroup , GeometryIndices ) ;
: : GeometryCollection : : AddGeometryProperties ( InCollection ) ;
2022-06-23 17:00:03 -04:00
const TArray < FSkelMeshRenderSection > & StaticMeshSections = SkeletalMesh - > GetResourceForRendering ( ) - > LODRenderData [ 0 ] . RenderSections ;
2022-09-16 19:43:53 -04:00
TManagedArray < FGeometryCollectionSection > & Sections = InCollection - > ModifyAttribute < FGeometryCollectionSection > ( " Sections " , FGeometryCollection : : MaterialGroup ) ;
2022-06-23 17:00:03 -04:00
for ( const FSkelMeshRenderSection & CurrSection : StaticMeshSections )
{
// create new section
2022-09-16 19:43:53 -04:00
int32 SectionIndex = InCollection - > AddElements ( 1 , FGeometryCollection : : MaterialGroup ) ;
2022-06-23 17:00:03 -04:00
Sections [ SectionIndex ] . MaterialID = MaterialStartIndex + CurrSection . MaterialIndex ;
Sections [ SectionIndex ] . FirstIndex = IndicesBaseIndex * 3 + CurrSection . BaseIndex ;
Sections [ SectionIndex ] . MinVertexIndex = VertexBaseIndex + CurrSection . BaseVertexIndex ;
Sections [ SectionIndex ] . NumTriangles = CurrSection . NumTriangles ;
// #todo(dmp): what should we set this to? SkeletalMesh sections are different
// but we are resetting this when the re indexing happens
Sections [ SectionIndex ] . MaxVertexIndex = VertexBaseIndex + CurrSection . NumVertices ;
// set the materialid for all of the faces
for ( int32 i = Sections [ SectionIndex ] . FirstIndex / 3 ; i < Sections [ SectionIndex ] . FirstIndex / 3 + Sections [ SectionIndex ] . NumTriangles ; + + i )
{
MaterialID [ i ] = SectionIndex ;
}
}
if ( bReindexMaterials )
{
2022-09-16 19:43:53 -04:00
FGeometryCollection : : ReindexMaterials ( * InCollection ) ;
2022-06-23 17:00:03 -04:00
}
return true ;
}
2022-09-21 11:52:44 -04:00
void FGeometryCollectionEngineConversion : : AppendSkeleton ( const USkeleton * InSkeleton , const FTransform & SkeletalMeshTransform , FManagedArrayCollection * InCollection )
{
//UE_LOG(UGeometryCollectionConversionLogging, Log, TEXT("FGeometryCollectionEngineConversion::AppendSkeletalMesh()"));
if ( ! InCollection | | ! InSkeleton )
{
return ;
}
FGeometryCollection : : DefineTransformSchema ( * InCollection ) ;
GeometryCollection : : Facades : : FTransformSource TransformSourceFacade ( InCollection ) ;
TManagedArray < FTransform > & Transform = InCollection - > ModifyAttribute < FTransform > ( FTransformCollection : : TransformAttribute , FTransformCollection : : TransformGroup ) ;
TManagedArray < FLinearColor > & BoneColor = InCollection - > ModifyAttribute < FLinearColor > ( " BoneColor " , FTransformCollection : : TransformGroup ) ;
TManagedArray < FString > & BoneName = InCollection - > ModifyAttribute < FString > ( " BoneName " , FTransformCollection : : TransformGroup ) ;
TManagedArray < int32 > & Parent = InCollection - > ModifyAttribute < int32 > ( FTransformCollection : : ParentAttribute , FTransformCollection : : TransformGroup ) ;
TManagedArray < TSet < int32 > > & Child = InCollection - > ModifyAttribute < TSet < int32 > > ( FTransformCollection : : ChildrenAttribute , FTransformCollection : : TransformGroup ) ;
const FReferenceSkeleton & Skeleton = InSkeleton - > GetReferenceSkeleton ( ) ;
int32 NumBones = Skeleton . GetNum ( ) ;
if ( NumBones )
{
const TArray < FTransform > & RestTransform = Skeleton . GetRefBonePose ( ) ;
const TArray < FMeshBoneInfo > & BoneInfo = Skeleton . GetRefBoneInfo ( ) ;
TSet < int32 > Roots ;
int32 TransformBaseIndex = InCollection - > AddElements ( NumBones , FGeometryCollection : : TransformGroup ) ;
for ( int i = 0 , Idx = TransformBaseIndex ; i < NumBones ; i + + , Idx + + )
{
Transform [ Idx ] = RestTransform [ i ] ;
BoneColor [ Idx ] = FLinearColor ( FColor ( FMath : : Rand ( ) % 100 + 5 , FMath : : Rand ( ) % 100 + 5 , FMath : : Rand ( ) % 100 + 5 , 255 ) ) ;
BoneName [ Idx ] = BoneInfo [ i ] . Name . ToString ( ) ;
Parent [ Idx ] = BoneInfo [ i ] . ParentIndex ;
if ( Parent [ Idx ] ! = INDEX_NONE )
{
Child [ Parent [ Idx ] ] . Add ( Idx ) ;
}
else
{
Roots . Add ( Idx ) ;
}
}
ensure ( Roots . Num ( ) ) ;
2022-10-06 21:52:53 -04:00
TransformSourceFacade . AddTransformSource ( InCollection , InSkeleton - > GetName ( ) , InSkeleton - > GetGuid ( ) . ToString ( ) , Roots ) ;
2022-09-21 11:52:44 -04:00
}
}
2022-06-23 17:00:03 -04:00
const FSkeletalMeshLODRenderData * FGeometryCollectionEngineConversion : : GetSkeletalMeshLOD ( const USkeletalMesh * SkeletalMesh , int32 LOD )
{
if ( const USkeleton * Skeleton = SkeletalMesh - > GetSkeleton ( ) )
{
if ( const FSkeletalMeshRenderData * SkelMeshRenderData = SkeletalMesh - > GetResourceForRendering ( ) )
{
if ( SkelMeshRenderData - > LODRenderData . IsValidIndex ( LOD ) )
{
return & SkelMeshRenderData - > LODRenderData [ LOD ] ;
}
}
}
return nullptr ;
}
void FGeometryCollectionEngineConversion : : AppendSkeletalMesh ( const USkeletalMesh * SkeletalMesh , const USkeletalMeshComponent * SkeletalMeshComponent , const FTransform & SkeletalMeshTransform , UGeometryCollection * GeometryCollectionObject , bool bReindexMaterials )
2022-06-01 21:41:57 -04:00
{
//UE_LOG(UGeometryCollectionConversionLogging, Log, TEXT("FGeometryCollectionEngineConversion::AppendSkeletalMesh()"));
check ( SkeletalMesh ) ;
if ( GeometryCollectionObject )
{
TSharedPtr < FGeometryCollection , ESPMode : : ThreadSafe > GeometryCollectionPtr = GeometryCollectionObject - > GetGeometryCollection ( ) ;
if ( FGeometryCollection * GeometryCollection = GeometryCollectionPtr . Get ( ) )
{
2022-06-23 17:00:03 -04:00
int32 MaterialStart = GeometryCollectionObject - > Materials . Num ( ) ;
if ( AppendSkeletalMesh ( SkeletalMesh , MaterialStart , SkeletalMeshTransform , GeometryCollection , bReindexMaterials ) )
2022-06-01 21:41:57 -04:00
{
2022-06-23 17:00:03 -04:00
AppendSkeletalMeshMaterials ( SkeletalMesh , SkeletalMeshComponent , GeometryCollectionObject ) ;
2022-06-01 21:41:57 -04:00
}
}
}
}
2022-06-23 17:00:03 -04:00
int32 FGeometryCollectionEngineConversion : : AppendSkeletalMeshMaterials ( const USkeletalMesh * SkeletalMesh , const USkeletalMeshComponent * SkeletalMeshComponent , UGeometryCollection * GeometryCollectionObject )
{
check ( SkeletalMesh ) ;
check ( SkeletalMeshComponent ) ;
check ( GeometryCollectionObject ) ;
const TArray < FSkeletalMaterial > & SkeletalMeshMaterials = SkeletalMesh - > GetMaterials ( ) ;
int32 CurrIdx = 0 ;
UMaterialInterface * CurrMaterial = SkeletalMeshComponent ? SkeletalMeshComponent - > GetMaterial ( CurrIdx ) : ToRawPtr ( SkeletalMeshMaterials [ CurrIdx ] . MaterialInterface ) ;
int MaterialStart = GeometryCollectionObject - > Materials . Num ( ) ;
while ( CurrMaterial )
{
GeometryCollectionObject - > Materials . Add ( CurrMaterial ) ;
CurrMaterial = SkeletalMeshComponent ? SkeletalMeshComponent - > GetMaterial ( + + CurrIdx ) : ToRawPtr ( SkeletalMeshMaterials [ + + CurrIdx ] . MaterialInterface ) ;
}
return MaterialStart ;
}