2022-10-21 19:51:57 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "GeometryCollection/GeometryCollectionISMPoolComponent.h"
# include "Components/HierarchicalInstancedStaticMeshComponent.h"
2022-10-22 17:33:07 -04:00
# include "Engine/CollisionProfile.h"
2022-10-21 19:52:03 -04:00
# include "Engine/StaticMesh.h"
2022-10-21 19:51:57 -04:00
# include "GeometryCollection/GeometryCollectionComponent.h"
2022-11-22 20:17:33 -05:00
# include UE_INLINE_GENERATED_CPP_BY_NAME(GeometryCollectionISMPoolComponent)
2023-04-14 17:05:40 -04:00
// Using a FreeList forces the calling of UnregisterComponent which can be
// slow if called many times in a frame. Disable for now, but can maybe enable
// if we defer and throttle UnregisterComponent calls.
static bool GUseComponentFreeList = false ;
2023-04-14 17:06:14 -04:00
FAutoConsoleVariableRef CVarISMPoolUseComponentFreeList (
2023-04-14 17:05:40 -04:00
TEXT ( " r.ISMPool.UseComponentFreeList " ) ,
GUseComponentFreeList ,
TEXT ( " Recycle ISM components in the Pool. " ) ) ;
2022-10-21 19:51:57 -04:00
FGeometryCollectionMeshGroup : : FMeshId FGeometryCollectionMeshGroup : : AddMesh ( const FGeometryCollectionStaticMeshInstance & MeshInstance , int32 InstanceCount , const FGeometryCollectionMeshInfo & ISMInstanceInfo )
{
FMeshId * MeshIndex = Meshes . Find ( MeshInstance ) ;
if ( MeshIndex )
{
return * MeshIndex ;
}
const FMeshId MeshInfoIndex = MeshInfos . Emplace ( ISMInstanceInfo ) ;
Meshes . Add ( MeshInstance , MeshInfoIndex ) ;
return MeshInfoIndex ;
}
bool FGeometryCollectionMeshGroup : : BatchUpdateInstancesTransforms ( FGeometryCollectionISMPool & ISMPool , FMeshId MeshId , int32 StartInstanceIndex , const TArray < FTransform > & NewInstancesTransforms , bool bWorldSpace , bool bMarkRenderStateDirty , bool bTeleport )
2023-05-25 18:53:40 -04:00
{
return BatchUpdateInstancesTransforms ( ISMPool , MeshId , StartInstanceIndex , MakeArrayView ( NewInstancesTransforms ) , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
}
bool FGeometryCollectionMeshGroup : : BatchUpdateInstancesTransforms ( FGeometryCollectionISMPool & ISMPool , FMeshId MeshId , int32 StartInstanceIndex , TArrayView < const FTransform > NewInstancesTransforms , bool bWorldSpace , bool bMarkRenderStateDirty , bool bTeleport )
2022-10-21 19:51:57 -04:00
{
if ( MeshInfos . IsValidIndex ( MeshId ) )
{
return ISMPool . BatchUpdateInstancesTransforms ( MeshInfos [ MeshId ] , StartInstanceIndex , NewInstancesTransforms , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
}
UE_LOG ( LogChaos , Warning , TEXT ( " UGeometryCollectionISMPoolComponent : Invalid mesh Id (%d) for this mesh group " ) , MeshId ) ;
return false ;
}
void FGeometryCollectionMeshGroup : : RemoveAllMeshes ( FGeometryCollectionISMPool & ISMPool )
{
for ( const FGeometryCollectionMeshInfo & MeshInfo : MeshInfos )
{
ISMPool . RemoveISM ( MeshInfo ) ;
}
MeshInfos . Empty ( ) ;
Meshes . Empty ( ) ;
}
2023-04-18 18:06:56 -04:00
FGeometryCollectionISM : : FGeometryCollectionISM ( AActor * InOwningActor , const FGeometryCollectionStaticMeshInstance & InMeshInstance )
2022-10-21 19:51:57 -04:00
{
2023-04-06 17:29:18 -04:00
MeshInstance = InMeshInstance ;
2022-10-21 19:51:57 -04:00
check ( MeshInstance . StaticMesh ) ;
2023-04-18 18:06:56 -04:00
check ( InOwningActor ) ;
2022-10-21 19:51:57 -04:00
2023-04-03 23:33:01 -04:00
UHierarchicalInstancedStaticMeshComponent * HISMC = nullptr ;
UInstancedStaticMeshComponent * ISMC = nullptr ;
if ( MeshInstance . Desc . bUseHISM )
2022-10-21 19:51:57 -04:00
{
2023-04-18 18:06:56 -04:00
const FName ISMName = MakeUniqueObjectName ( InOwningActor , UHierarchicalInstancedStaticMeshComponent : : StaticClass ( ) , MeshInstance . StaticMesh - > GetFName ( ) ) ;
ISMC = HISMC = NewObject < UHierarchicalInstancedStaticMeshComponent > ( InOwningActor , ISMName , RF_Transient | RF_DuplicateTransient ) ;
2022-10-21 19:51:57 -04:00
}
2023-04-03 23:33:01 -04:00
else
{
2023-04-18 18:06:56 -04:00
const FName ISMName = MakeUniqueObjectName ( InOwningActor , UInstancedStaticMeshComponent : : StaticClass ( ) , MeshInstance . StaticMesh - > GetFName ( ) ) ;
ISMC = NewObject < UInstancedStaticMeshComponent > ( InOwningActor , ISMName , RF_Transient | RF_DuplicateTransient ) ;
2023-04-03 23:33:01 -04:00
}
if ( ! ensure ( ISMC ! = nullptr ) )
{
return ;
}
ISMC - > SetStaticMesh ( MeshInstance . StaticMesh ) ;
for ( int32 MaterialIndex = 0 ; MaterialIndex < MeshInstance . MaterialsOverrides . Num ( ) ; MaterialIndex + + )
{
ISMC - > SetMaterial ( MaterialIndex , MeshInstance . MaterialsOverrides [ MaterialIndex ] ) ;
}
2023-05-06 02:08:34 -04:00
for ( int32 DataIndex = 0 ; DataIndex < MeshInstance . CustomPrimitiveData . Num ( ) ; DataIndex + + )
{
2023-06-08 19:39:06 -04:00
ISMC - > SetDefaultCustomPrimitiveDataFloat ( DataIndex , MeshInstance . CustomPrimitiveData [ DataIndex ] ) ;
2023-05-06 02:08:34 -04:00
}
2023-04-03 23:33:01 -04:00
2023-04-14 17:05:40 -04:00
ISMC - > SetRemoveSwap ( ) ;
2023-04-03 23:33:01 -04:00
ISMC - > NumCustomDataFloats = MeshInstance . Desc . NumCustomDataFloats ;
2023-04-06 17:29:18 -04:00
ISMC - > SetReverseCulling ( MeshInstance . Desc . bReverseCulling ) ;
2023-04-03 23:33:01 -04:00
ISMC - > SetMobility ( MeshInstance . Desc . bIsStaticMobility ? EComponentMobility : : Static : EComponentMobility : : Stationary ) ;
ISMC - > SetCullDistances ( MeshInstance . Desc . StartCullDistance , MeshInstance . Desc . EndCullDistance ) ;
ISMC - > SetCastShadow ( MeshInstance . Desc . bAffectShadow ) ;
ISMC - > bAffectDynamicIndirectLighting = MeshInstance . Desc . bAffectDynamicIndirectLighting ;
ISMC - > bAffectDistanceFieldLighting = MeshInstance . Desc . bAffectDistanceFieldLighting ;
ISMC - > SetCanEverAffectNavigation ( false ) ;
ISMC - > SetCollisionEnabled ( ECollisionEnabled : : NoCollision ) ;
2023-04-10 23:19:28 -04:00
ISMC - > bOverrideMinLOD = MeshInstance . Desc . MinLod > 0 ;
ISMC - > MinLOD = MeshInstance . Desc . MinLod ;
2023-06-08 19:39:06 -04:00
ISMC - > ComponentTags . Append ( MeshInstance . Desc . Tags ) ;
2023-04-03 23:33:01 -04:00
if ( HISMC )
{
HISMC - > SetLODDistanceScale ( MeshInstance . Desc . LodScale ) ;
}
2023-06-08 19:39:06 -04:00
2023-04-18 18:06:56 -04:00
InOwningActor - > AddInstanceComponent ( ISMC ) ;
2023-04-03 23:33:01 -04:00
ISMC - > RegisterComponent ( ) ;
2023-06-16 19:32:24 -04:00
ISMC - > SetVisibility ( false ) ;
2023-04-03 23:33:01 -04:00
ISMComponent = ISMC ;
2022-10-21 19:51:57 -04:00
}
2023-04-14 09:07:04 -04:00
FInstanceGroups : : FInstanceGroupId FGeometryCollectionISM : : AddInstanceGroup ( int32 InstanceCount , TArrayView < const float > CustomDataFloats )
2022-10-21 19:51:57 -04:00
{
2023-03-21 17:54:35 -04:00
// When adding new group it will always have a single range
2023-04-14 09:07:04 -04:00
const FInstanceGroups : : FInstanceGroupId InstanceGroupIndex = InstanceGroups . AddGroup ( InstanceCount ) ;
const FInstanceGroups : : FInstanceGroupRange & NewInstanceGroup = InstanceGroups . GroupRanges [ InstanceGroupIndex ] ;
2023-03-06 15:17:02 -05:00
2022-10-29 03:00:57 -04:00
FTransform ZeroScaleTransform ;
ZeroScaleTransform . SetIdentityZeroScale ( ) ;
2023-03-06 15:17:02 -05:00
TArray < FTransform > ZeroScaleTransforms ;
ZeroScaleTransforms . Init ( ZeroScaleTransform , InstanceCount ) ;
2023-06-16 19:32:24 -04:00
ISMComponent - > SetVisibility ( true ) ;
2023-04-14 09:07:04 -04:00
ISMComponent - > PreAllocateInstancesMemory ( InstanceCount ) ;
TArray < int32 > RenderInstances = ISMComponent - > AddInstances ( ZeroScaleTransforms , true , true ) ;
2023-03-06 15:17:02 -05:00
2023-04-14 09:07:04 -04:00
// Ensure that remapping arrays are big enough to hold any new items.
InstanceIndexToRenderIndex . SetNum ( InstanceGroups . GetMaxInstanceIndex ( ) , false ) ;
RenderIndexToInstanceIndex . SetNum ( ISMComponent - > PerInstanceSMData . Num ( ) , false ) ;
// Store mapping between our fixed instance index and the mutable ISM render index.
// todo: Improve ISM API so that we don't need to pay the memory overhead here to manage this.
for ( int32 InstanceIndex = 0 ; InstanceIndex < InstanceCount ; + + InstanceIndex )
{
InstanceIndexToRenderIndex [ NewInstanceGroup . Start + InstanceIndex ] = RenderInstances [ InstanceIndex ] ;
RenderIndexToInstanceIndex [ RenderInstances [ InstanceIndex ] ] = NewInstanceGroup . Start + InstanceIndex ;
}
// Set any custom data.
2023-03-08 23:38:52 -05:00
if ( CustomDataFloats . Num ( ) )
{
const int32 NumCustomDataFloats = ISMComponent - > NumCustomDataFloats ;
if ( ensure ( NumCustomDataFloats * InstanceCount = = CustomDataFloats . Num ( ) ) )
{
for ( int32 InstanceIndex = 0 ; InstanceIndex < InstanceCount ; + + InstanceIndex )
{
2023-04-14 09:07:04 -04:00
ISMComponent - > SetCustomData ( RenderInstances [ InstanceIndex ] , CustomDataFloats . Slice ( InstanceIndex * NumCustomDataFloats , NumCustomDataFloats ) ) ;
2023-03-08 23:38:52 -05:00
}
}
}
2022-10-21 19:51:57 -04:00
return InstanceGroupIndex ;
}
2023-04-18 18:06:56 -04:00
FGeometryCollectionISMPool : : FISMIndex FGeometryCollectionISMPool : : AddISM ( UGeometryCollectionISMPoolComponent * OwningComponent , const FGeometryCollectionStaticMeshInstance & MeshInstance )
2022-10-21 19:51:57 -04:00
{
2023-04-18 18:06:56 -04:00
FISMIndex * ISMIndexPtr = MeshToISMIndex . Find ( MeshInstance ) ;
if ( ISMIndexPtr ! = nullptr )
2022-10-21 19:51:57 -04:00
{
2023-04-18 18:06:56 -04:00
return * ISMIndexPtr ;
}
FISMIndex ISMIndex = INDEX_NONE ;
if ( FreeList . Num ( ) )
{
// Take an ISM from the current FreeList instead of allocating a new slot.
ISMIndex = FreeList . Last ( ) ;
FreeList . RemoveAt ( FreeList . Num ( ) - 1 ) ;
ISMs [ ISMIndex ] = FGeometryCollectionISM ( OwningComponent - > GetOwner ( ) , MeshInstance ) ;
2022-10-21 19:51:57 -04:00
}
else
{
2023-04-18 18:06:56 -04:00
ISMIndex = ISMs . Emplace ( OwningComponent - > GetOwner ( ) , MeshInstance ) ;
2022-10-21 19:51:57 -04:00
}
2023-04-18 18:06:56 -04:00
MeshToISMIndex . Add ( MeshInstance , ISMIndex ) ;
return ISMIndex ;
}
FGeometryCollectionMeshInfo FGeometryCollectionISMPool : : AddISM ( UGeometryCollectionISMPoolComponent * OwningComponent , const FGeometryCollectionStaticMeshInstance & MeshInstance , int32 InstanceCount , TArrayView < const float > CustomDataFloats )
{
FGeometryCollectionMeshInfo Info ;
Info . ISMIndex = AddISM ( OwningComponent , MeshInstance ) ;
2023-03-08 23:38:52 -05:00
Info . InstanceGroupIndex = ISMs [ Info . ISMIndex ] . AddInstanceGroup ( InstanceCount , CustomDataFloats ) ;
2022-10-21 19:51:57 -04:00
return Info ;
}
bool FGeometryCollectionISMPool : : BatchUpdateInstancesTransforms ( FGeometryCollectionMeshInfo & MeshInfo , int32 StartInstanceIndex , const TArray < FTransform > & NewInstancesTransforms , bool bWorldSpace , bool bMarkRenderStateDirty , bool bTeleport )
{
2023-05-25 18:53:40 -04:00
return BatchUpdateInstancesTransforms ( MeshInfo , StartInstanceIndex , MakeArrayView ( NewInstancesTransforms ) , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
}
bool FGeometryCollectionISMPool : : BatchUpdateInstancesTransforms ( FGeometryCollectionMeshInfo & MeshInfo , int32 StartInstanceIndex , TArrayView < const FTransform > NewInstancesTransforms , bool bWorldSpace , bool bMarkRenderStateDirty , bool bTeleport )
{
constexpr bool bUseArrayView = true ;
2022-10-21 19:51:57 -04:00
if ( ISMs . IsValidIndex ( MeshInfo . ISMIndex ) )
{
FGeometryCollectionISM & ISM = ISMs [ MeshInfo . ISMIndex ] ;
2023-04-14 09:07:04 -04:00
const FInstanceGroups : : FInstanceGroupRange & InstanceGroup = ISM . InstanceGroups . GroupRanges [ MeshInfo . InstanceGroupIndex ] ;
ensure ( ( StartInstanceIndex + NewInstancesTransforms . Num ( ) ) < = InstanceGroup . Count ) ;
2022-10-21 19:51:57 -04:00
2023-05-15 15:51:09 -04:00
// If ISM component has identity transform (the common case) then we can skip world space to component space maths inside BatchUpdateInstancesTransforms()
bWorldSpace & = ! ISM . ISMComponent - > GetComponentTransform ( ) . Equals ( FTransform : : Identity , 0.f ) ;
2023-04-14 09:07:04 -04:00
int32 StartIndex = ISM . InstanceIndexToRenderIndex [ InstanceGroup . Start ] ;
2023-03-21 17:54:35 -04:00
int32 TransformIndex = 0 ;
int32 BatchCount = 1 ;
2023-05-25 18:53:40 -04:00
if constexpr ( bUseArrayView )
{
for ( int InstanceIndex = StartInstanceIndex + 1 ; InstanceIndex < NewInstancesTransforms . Num ( ) ; + + InstanceIndex )
{
// Flush batch for non-sequential instances.
int32 RenderIndex = ISM . InstanceIndexToRenderIndex [ InstanceGroup . Start + InstanceIndex ] ;
if ( RenderIndex ! = ( StartIndex + BatchCount ) )
{
TArrayView < const FTransform > BatchedTransformsView = MakeArrayView ( NewInstancesTransforms . GetData ( ) + TransformIndex , BatchCount ) ;
ISM . ISMComponent - > BatchUpdateInstancesTransforms ( StartIndex , BatchedTransformsView , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
StartIndex = RenderIndex ;
TransformIndex + = BatchCount ;
BatchCount = 0 ;
}
BatchCount + + ;
}
// last one
TArrayView < const FTransform > BatchedTransformsView = MakeArrayView ( NewInstancesTransforms . GetData ( ) + TransformIndex , BatchCount ) ;
return ISM . ISMComponent - > BatchUpdateInstancesTransforms ( StartIndex , BatchedTransformsView , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
}
else
{
TArray < FTransform > BatchTransforms ; // Can't use TArrayView because blueprint function doesn't support that
BatchTransforms . Reserve ( NewInstancesTransforms . Num ( ) ) ;
BatchTransforms . Add ( NewInstancesTransforms [ TransformIndex + + ] ) ;
for ( int InstanceIndex = StartInstanceIndex + 1 ; InstanceIndex < NewInstancesTransforms . Num ( ) ; + + InstanceIndex )
{
// Flush batch for non-sequential instances.
int32 RenderIndex = ISM . InstanceIndexToRenderIndex [ InstanceGroup . Start + InstanceIndex ] ;
if ( RenderIndex ! = ( StartIndex + BatchCount ) )
{
ISM . ISMComponent - > BatchUpdateInstancesTransforms ( StartIndex , BatchTransforms , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
StartIndex = RenderIndex ;
BatchTransforms . SetNum ( 0 , false ) ;
BatchCount = 0 ;
}
BatchTransforms . Add ( NewInstancesTransforms [ TransformIndex + + ] ) ;
BatchCount + + ;
}
return ISM . ISMComponent - > BatchUpdateInstancesTransforms ( StartIndex , BatchTransforms , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
}
2022-10-21 19:51:57 -04:00
}
UE_LOG ( LogChaos , Warning , TEXT ( " UGeometryCollectionISMPoolComponent : Invalid ISM Id (%d) when updating the transform " ) , MeshInfo . ISMIndex ) ;
return false ;
}
void FGeometryCollectionISMPool : : RemoveISM ( const FGeometryCollectionMeshInfo & MeshInfo )
{
if ( ISMs . IsValidIndex ( MeshInfo . ISMIndex ) )
{
FGeometryCollectionISM & ISM = ISMs [ MeshInfo . ISMIndex ] ;
2023-04-14 09:07:04 -04:00
const FInstanceGroups : : FInstanceGroupRange & InstanceGroup = ISM . InstanceGroups . GroupRanges [ MeshInfo . InstanceGroupIndex ] ;
TArray < int32 > InstancesToRemove ;
InstancesToRemove . SetNum ( InstanceGroup . Count ) ;
for ( int32 InstanceIndex = 0 ; InstanceIndex < InstanceGroup . Count ; + + InstanceIndex )
{
2023-04-14 17:05:40 -04:00
// We need render index to pass to the ISMComponent.
2023-04-14 09:07:04 -04:00
InstancesToRemove [ InstanceIndex ] = ISM . InstanceIndexToRenderIndex [ InstanceGroup . Start + InstanceIndex ] ;
2023-04-14 17:05:40 -04:00
// Clear the stored render index since we're about to remove it.
ISM . InstanceIndexToRenderIndex [ InstanceGroup . Start + InstanceIndex ] = - 1 ;
2023-04-14 09:07:04 -04:00
}
2023-05-25 18:53:40 -04:00
// we sort the array on the spot because we use it after calling RemoveInstances to fix up our own indices
InstancesToRemove . Sort ( TGreater < int32 > ( ) ) ;
constexpr bool bArrayAlreadySorted = true ;
ISM . ISMComponent - > RemoveInstances ( InstancesToRemove , bArrayAlreadySorted ) ;
2023-04-14 09:07:04 -04:00
2023-04-14 17:05:40 -04:00
// Fix up instance index remapping to match what will have happened in our ISM component in RemoveInstances()
check ( ISM . ISMComponent - > SupportsRemoveSwap ( ) ) ;
for ( int32 RenderIndex : InstancesToRemove )
{
ISM . RenderIndexToInstanceIndex . RemoveAtSwap ( RenderIndex , 1 , false ) ;
if ( RenderIndex < ISM . RenderIndexToInstanceIndex . Num ( ) )
{
const int32 MovedInstanceIndex = ISM . RenderIndexToInstanceIndex [ RenderIndex ] ;
ISM . InstanceIndexToRenderIndex [ MovedInstanceIndex ] = RenderIndex ;
}
}
2022-10-21 19:51:57 -04:00
ISM . InstanceGroups . RemoveGroup ( MeshInfo . InstanceGroupIndex ) ;
2023-04-06 17:29:18 -04:00
2023-04-18 18:06:56 -04:00
if ( ISM . InstanceGroups . IsEmpty ( ) )
2023-04-06 17:29:18 -04:00
{
2023-04-18 18:06:56 -04:00
// No live instances, so take opportunity to reset indexing.
2023-04-14 09:07:04 -04:00
ISM . InstanceGroups . Reset ( ) ;
2023-04-14 17:05:40 -04:00
ISM . InstanceIndexToRenderIndex . Reset ( ) ;
ISM . RenderIndexToInstanceIndex . Reset ( ) ;
2023-06-16 19:32:24 -04:00
ISM . ISMComponent - > SetVisibility ( false ) ;
2023-04-18 18:06:56 -04:00
}
if ( GUseComponentFreeList & & ISM . ISMComponent - > PerInstanceSMData . Num ( ) = = 0 )
{
// Remove component and push this ISM slot to the free list.
// todo: profile if it is better to push component into a free pool and recycle it.
ISM . ISMComponent - > GetOwner ( ) - > RemoveInstanceComponent ( ISM . ISMComponent ) ;
ISM . ISMComponent - > UnregisterComponent ( ) ;
ISM . ISMComponent - > DestroyComponent ( ) ;
2023-04-14 17:05:40 -04:00
2023-04-18 18:06:56 -04:00
MeshToISMIndex . Remove ( ISM . MeshInstance ) ;
FreeList . Add ( MeshInfo . ISMIndex ) ;
ISM . ISMComponent = nullptr ;
2023-03-21 17:54:35 -04:00
}
}
}
2022-10-21 19:51:57 -04:00
void FGeometryCollectionISMPool : : Clear ( )
{
MeshToISMIndex . Reset ( ) ;
2023-04-06 17:29:18 -04:00
FreeList . Reset ( ) ;
2022-10-21 19:51:57 -04:00
if ( ISMs . Num ( ) > 0 )
{
if ( AActor * OwningActor = ISMs [ 0 ] . ISMComponent - > GetOwner ( ) )
{
for ( FGeometryCollectionISM & ISM : ISMs )
{
ISM . ISMComponent - > UnregisterComponent ( ) ;
ISM . ISMComponent - > DestroyComponent ( ) ;
OwningActor - > RemoveInstanceComponent ( ISM . ISMComponent ) ;
}
}
ISMs . Reset ( ) ;
}
}
UGeometryCollectionISMPoolComponent : : UGeometryCollectionISMPoolComponent ( const FObjectInitializer & ObjectInitializer )
: NextMeshGroupId ( 0 )
{
}
UGeometryCollectionISMPoolComponent : : FMeshGroupId UGeometryCollectionISMPoolComponent : : CreateMeshGroup ( )
{
MeshGroups . Add ( NextMeshGroupId ) ;
return NextMeshGroupId + + ;
}
void UGeometryCollectionISMPoolComponent : : DestroyMeshGroup ( FMeshGroupId MeshGroupId )
{
if ( FGeometryCollectionMeshGroup * MeshGroup = MeshGroups . Find ( MeshGroupId ) )
{
MeshGroup - > RemoveAllMeshes ( Pool ) ;
MeshGroups . Remove ( MeshGroupId ) ;
}
}
2023-04-03 23:33:01 -04:00
UGeometryCollectionISMPoolComponent : : FMeshId UGeometryCollectionISMPoolComponent : : AddMeshToGroup ( FMeshGroupId MeshGroupId , const FGeometryCollectionStaticMeshInstance & MeshInstance , int32 InstanceCount , TArrayView < const float > CustomDataFloats )
2022-10-21 19:51:57 -04:00
{
if ( FGeometryCollectionMeshGroup * MeshGroup = MeshGroups . Find ( MeshGroupId ) )
{
2023-04-03 23:33:01 -04:00
const FGeometryCollectionMeshInfo ISMInstanceInfo = Pool . AddISM ( this , MeshInstance , InstanceCount , CustomDataFloats ) ;
2022-10-21 19:51:57 -04:00
return MeshGroup - > AddMesh ( MeshInstance , InstanceCount , ISMInstanceInfo ) ;
}
UE_LOG ( LogChaos , Warning , TEXT ( " UGeometryCollectionISMPoolComponent : Trying to add a mesh to a mesh group (%d) that does not exists " ) , MeshGroupId ) ;
return INDEX_NONE ;
}
bool UGeometryCollectionISMPoolComponent : : BatchUpdateInstancesTransforms ( FMeshGroupId MeshGroupId , FMeshId MeshId , int32 StartInstanceIndex , const TArray < FTransform > & NewInstancesTransforms , bool bWorldSpace , bool bMarkRenderStateDirty , bool bTeleport )
2023-05-25 18:53:40 -04:00
{
return BatchUpdateInstancesTransforms ( MeshGroupId , MeshId , StartInstanceIndex , MakeArrayView ( NewInstancesTransforms ) , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
}
bool UGeometryCollectionISMPoolComponent : : BatchUpdateInstancesTransforms ( FMeshGroupId MeshGroupId , FMeshId MeshId , int32 StartInstanceIndex , TArrayView < const FTransform > NewInstancesTransforms , bool bWorldSpace , bool bMarkRenderStateDirty , bool bTeleport )
2022-10-21 19:51:57 -04:00
{
if ( FGeometryCollectionMeshGroup * MeshGroup = MeshGroups . Find ( MeshGroupId ) )
{
return MeshGroup - > BatchUpdateInstancesTransforms ( Pool , MeshId , StartInstanceIndex , NewInstancesTransforms , bWorldSpace , bMarkRenderStateDirty , bTeleport ) ;
}
UE_LOG ( LogChaos , Warning , TEXT ( " UGeometryCollectionISMPoolComponent : Trying to update instance with mesh group (%d) that not exists " ) , MeshGroupId ) ;
return false ;
}
2023-04-14 09:07:04 -04:00
2023-04-18 18:06:56 -04:00
void UGeometryCollectionISMPoolComponent : : PreallocateMeshInstance ( const FGeometryCollectionStaticMeshInstance & MeshInstance )
{
// If we are recycling components with a free list then we don't expect to have zero instance components.
// So don't do preallocation of components either in that case.
if ( ! GUseComponentFreeList )
{
Pool . AddISM ( this , MeshInstance ) ;
}
}
2023-04-14 09:07:04 -04:00
void UGeometryCollectionISMPoolComponent : : GetResourceSizeEx ( FResourceSizeEx & CumulativeResourceSize )
{
Super : : GetResourceSizeEx ( CumulativeResourceSize ) ;
int32 SizeBytes =
MeshGroups . GetAllocatedSize ( )
+ Pool . MeshToISMIndex . GetAllocatedSize ( )
+ Pool . ISMs . GetAllocatedSize ( )
+ Pool . FreeList . GetAllocatedSize ( ) ;
for ( FGeometryCollectionISM ISM : Pool . ISMs )
{
SizeBytes + = ISM . InstanceIndexToRenderIndex . GetAllocatedSize ( )
+ ISM . RenderIndexToInstanceIndex . GetAllocatedSize ( )
+ ISM . InstanceGroups . GroupRanges . GetAllocatedSize ( )
+ ISM . InstanceGroups . FreeList . GetAllocatedSize ( ) ;
}
CumulativeResourceSize . AddDedicatedSystemMemoryBytes ( SizeBytes ) ;
}