Files
UnrealEngineUWP/Engine/Source/Runtime/Experimental/GeometryCollectionEngine/Public/GeometryCollection/GeometryCollectionObject.h
jeremy moore 644ac38dc2 GeometryCollection object can store custom instance data to pass to instances spawned in ISM pools.
Also add a per component custom data which, if present, is added to all ISM pool instances that the component generates.
#preflight 6409444bcf5fe1e28c0e065c

[CL 24571716 by jeremy moore in ue5-main branch]
2023-03-08 23:38:52 -05:00

788 lines
29 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Chaos/ChaosSolverActor.h"
#include "GeometryCollection/GeometryCollectionDamagePropagationData.h"
#include "GeometryCollection/GeometryCollectionSimulationTypes.h"
#include "GeometryCollection/ManagedArray.h"
#include "InstanceUniformShaderParameters.h"
#include "Interfaces/Interface_AssetUserData.h"
#include "Misc/Crc.h"
#include "GeometryCollectionObject.generated.h"
class FGeometryCollection;
class FGeometryCollectionRenderData;
struct FGeometryCollectionSection;
struct FManagedArrayCollection;
struct FSharedSimulationParameters;
class UDataflow;
class UGeometryCollectionCache;
class UMaterial;
class UMaterialInterface;
USTRUCT(BlueprintType)
struct GEOMETRYCOLLECTIONENGINE_API FGeometryCollectionSource
{
GENERATED_BODY()
FGeometryCollectionSource() {}
FGeometryCollectionSource(const FSoftObjectPath& SourceSoftObjectPath, const FTransform& ComponentTransform, const TArray<TObjectPtr<UMaterialInterface>>& SourceMaterials, bool bSplitComponents = false, bool bSetInternalFromMaterialIndex = false)
: SourceGeometryObject(SourceSoftObjectPath), LocalTransform(ComponentTransform), SourceMaterial(SourceMaterials), bAddInternalMaterials(false), bSplitComponents(bSplitComponents), bSetInternalFromMaterialIndex(bSetInternalFromMaterialIndex)
{
}
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GeometrySource", meta=(AllowedClasses="/Script/Engine.StaticMesh, /Script/Engine.SkeletalMesh, /Script/GeometryCollectionEngine.GeometryCollection"))
FSoftObjectPath SourceGeometryObject;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GeometrySource")
FTransform LocalTransform;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GeometrySource")
TArray<TObjectPtr<UMaterialInterface>> SourceMaterial;
//~ Note: bAddInternalMaterials defaults to true so a 'Reset' of a geometry collection that was created before this member was added will have consistent behavior. New geometry collections should always set bAddInternalMaterials to false.
/** (Legacy) Whether source materials will be duplicated to create new slots for internal materials, or existing odd materials will be considered internal. (For non-Geometry Collection inputs only.) */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GeometrySource", DisplayName = "(Legacy) Add Internal Materials")
bool bAddInternalMaterials = true;
/** Whether individual source mesh components should be split into separate pieces of geometry based on mesh connectivity. If checked, triangles that are not topologically connected will be assigned separate bones. (For non-Geometry Collection inputs only.) */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GeometrySource", DisplayName = "Split Meshes")
bool bSplitComponents = false;
/** Whether to set the 'internal' flag for faces with odd-numbered materials slots. */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GeometrySource")
bool bSetInternalFromMaterialIndex = false;
// TODO: add primtive custom data
};
USTRUCT(BlueprintType)
struct GEOMETRYCOLLECTIONENGINE_API FGeometryCollectionAutoInstanceMesh
{
GENERATED_BODY()
#if WITH_EDITORONLY_DATA
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Mesh instead."))
FSoftObjectPath StaticMesh_DEPRECATED;
#endif
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AutoInstance", meta = (AllowedClasses = "/Script/Engine.StaticMesh"))
TObjectPtr<const UStaticMesh> Mesh;
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "AutoInstance")
TArray<TObjectPtr<UMaterialInterface>> Materials;
bool operator ==(const FGeometryCollectionAutoInstanceMesh& Other) const;
};
USTRUCT(BlueprintType)
struct GEOMETRYCOLLECTIONENGINE_API FGeometryCollectionEmbeddedExemplar
{
GENERATED_BODY()
FGeometryCollectionEmbeddedExemplar()
: StaticMeshExemplar(FString(TEXT("None")))
, StartCullDistance(0.0f)
, EndCullDistance(0.0f)
, InstanceCount(0)
{ };
FGeometryCollectionEmbeddedExemplar(FSoftObjectPath NewExemplar)
: StaticMeshExemplar(NewExemplar)
, StartCullDistance(0.0f)
, EndCullDistance(0.0f)
, InstanceCount(0)
{ }
UPROPERTY(EditAnywhere, Category = "EmbeddedExemplar", meta = (AllowedClasses = "/Script/Engine.StaticMesh"))
FSoftObjectPath StaticMeshExemplar;
UPROPERTY(EditAnywhere, Category = "EmbeddedExemplar")
float StartCullDistance;
UPROPERTY(EditAnywhere, Category = "EmbeddedExemplar")
float EndCullDistance;
UPROPERTY(VisibleAnywhere, Category = "EmbeddedExemplar")
int32 InstanceCount;
};
USTRUCT()
struct GEOMETRYCOLLECTIONENGINE_API FGeometryCollectionLevelSetData
{
GENERATED_BODY()
FGeometryCollectionLevelSetData();
/*
* Resolution on the smallest axes for the level set. (def: 5)
*/
UPROPERTY(EditAnywhere, Category = "LevelSet")
int32 MinLevelSetResolution;
/*
* Resolution on the smallest axes for the level set. (def: 10)
*/
UPROPERTY(EditAnywhere, Category = "LevelSet")
int32 MaxLevelSetResolution;
/*
* Resolution on the smallest axes for the level set. (def: 5)
*/
UPROPERTY(EditAnywhere, Category = "LevelSet")
int32 MinClusterLevelSetResolution;
/*
* Resolution on the smallest axes for the level set. (def: 10)
*/
UPROPERTY(EditAnywhere, Category = "LevelSet")
int32 MaxClusterLevelSetResolution;
};
USTRUCT()
struct GEOMETRYCOLLECTIONENGINE_API FGeometryCollectionCollisionParticleData
{
GENERATED_BODY()
FGeometryCollectionCollisionParticleData();
/**
* Number of particles on the triangulated surface to use for collisions.
*/
UPROPERTY(EditAnywhere, Category = "Particle")
float CollisionParticlesFraction;
/**
* Max number of particles.
*/
UPROPERTY(EditAnywhere, Category = "Particle")
int32 MaximumCollisionParticles;
};
USTRUCT()
struct GEOMETRYCOLLECTIONENGINE_API FGeometryCollectionCollisionTypeData
{
GENERATED_BODY()
FGeometryCollectionCollisionTypeData();
/*
* CollisionType defines how to initialize the rigid collision structures.
*/
UPROPERTY(EditAnywhere, Category = "Collisions")
ECollisionTypeEnum CollisionType;
/*
* CollisionType defines how to initialize the rigid collision structures.
*/
UPROPERTY(EditAnywhere, Category = "Collisions")
EImplicitTypeEnum ImplicitType;
/*
* LevelSet Resolution data for rasterization.
*/
UPROPERTY(EditAnywhere, Category = "Collisions", meta = (EditCondition = "ImplicitType == EImplicitTypeEnum::Chaos_Implicit_LevelSet", EditConditionHides))
FGeometryCollectionLevelSetData LevelSet;
/*
* Collision Particle data for surface samples during Particle-LevelSet collisions.
*/
UPROPERTY(EditAnywhere, Category = "Collisions", meta = (EditCondition = "CollisionType == ECollisionTypeEnum::Chaos_Surface_Volumetric", EditConditionHides))
FGeometryCollectionCollisionParticleData CollisionParticles;
/*
* Uniform scale on the collision body. (def: 0)
*/
UPROPERTY(EditAnywhere, Category = "Collisions")
float CollisionObjectReductionPercentage;
/**
* A collision margin is a fraction of size used by some boxes and convex shapes to improve collision detection results.
* The core geometry of shapes that support a margin are reduced in size by the margin, and the margin
* is added back on during collision detection. The net result is a shape of the same size but with rounded corners.
*/
UPROPERTY(EditAnywhere, Category = "Collisions", meta = (EditCondition = "ImplicitType == EImplicitTypeEnum::Chaos_Implicit_Convex || ImplicitType == EImplicitTypeEnum::Chaos_Implicit_Box", EditConditionHides))
float CollisionMarginFraction;
};
USTRUCT()
struct GEOMETRYCOLLECTIONENGINE_API FGeometryCollectionSizeSpecificData
{
GENERATED_BODY()
FGeometryCollectionSizeSpecificData();
/** The max size these settings apply to*/
UPROPERTY(EditAnywhere, Category = "Collisions")
float MaxSize;
/*
* Collision Shapes allow kfor multiple collision types per rigid body.
*/
UPROPERTY(EditAnywhere, Category = "Collisions")
TArray<FGeometryCollectionCollisionTypeData> CollisionShapes;
#if WITH_EDITORONLY_DATA
/*
* CollisionType defines how to initialize the rigid collision structures.
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.CollisionType instead."))
ECollisionTypeEnum CollisionType_DEPRECATED;
/*
* CollisionType defines how to initialize the rigid collision structures.
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.ImplicitType instead."))
EImplicitTypeEnum ImplicitType_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 5)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.LevelSet.MinLevelSetResolution instead."))
int32 MinLevelSetResolution_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 10)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.LevelSet.MaxLevelSetResolution instead."))
int32 MaxLevelSetResolution_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 5)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.LevelSet.MinClusterLevelSetResolution instead."))
int32 MinClusterLevelSetResolution_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 10)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.LevelSet.MaxClusterLevelSetResolution instead."))
int32 MaxClusterLevelSetResolution_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 10)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.CollisionObjectReductionPercentage instead."))
int32 CollisionObjectReductionPercentage_DEPRECATED;
/**
* Number of particles on the triangulated surface to use for collisions.
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.CollisionParticlesFraction instead."))
float CollisionParticlesFraction_DEPRECATED;
/**
* Max number of particles.
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use Collision.MaximumCollisionParticles instead."))
int32 MaximumCollisionParticles_DEPRECATED;
#endif
/**
* Max number of particles.
*/
UPROPERTY(EditAnywhere, Category = "Collisions")
int32 DamageThreshold;
bool Serialize(FArchive& Ar);
#if WITH_EDITORONLY_DATA
void PostSerialize(const FArchive& Ar);
#endif
};
template<>
struct TStructOpsTypeTraits<FGeometryCollectionSizeSpecificData> : public TStructOpsTypeTraitsBase2<FGeometryCollectionSizeSpecificData>
{
enum
{
WithSerializer = true,
#if WITH_EDITORONLY_DATA
WithPostSerialize = true
#endif
};
};
USTRUCT(BlueprintType)
struct GEOMETRYCOLLECTIONENGINE_API FGeometryCollectionProxyMeshData
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Rendering", meta = (AllowedClasses = "/Script/Engine.StaticMesh"))
TArray<TObjectPtr<UStaticMesh>> ProxyMeshes;
};
/**
* UGeometryCollectionObject (UObject)
*
* UObject wrapper for the FGeometryCollection
*
*/
UCLASS(BlueprintType, customconstructor)
class GEOMETRYCOLLECTIONENGINE_API UGeometryCollection : public UObject, public IInterface_AssetUserData
{
GENERATED_UCLASS_BODY()
public:
UGeometryCollection(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());
/** UObject Interface */
#if WITH_EDITOR
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
virtual bool Modify(bool bAlwaysMarkDirty = true) override;
#endif
virtual void PostInitProperties() override;
virtual void PostLoad() override;
virtual void BeginDestroy() override;
/** End UObject Interface */
void Serialize(FArchive& Ar);
#if WITH_EDITORONLY_DATA
void PostSerialize(const FArchive& Ar);
#endif
#if WITH_EDITOR
void EnsureDataIsCooked(bool bInitResources, bool bIsTransacting, bool bIsPersistant, bool bAllowCopyFromDDC = true);
#endif
/** Accessors for internal geometry collection */
void SetGeometryCollection(TSharedPtr<FGeometryCollection, ESPMode::ThreadSafe> GeometryCollectionIn) { GeometryCollection = GeometryCollectionIn; }
TSharedPtr<FGeometryCollection, ESPMode::ThreadSafe> GetGeometryCollection() { return GeometryCollection; }
const TSharedPtr<FGeometryCollection, ESPMode::ThreadSafe> GetGeometryCollection() const { return GeometryCollection; }
/** Return collection to initial (ie. empty) state. */
void Reset();
/** Reset the collection from another set of attributes and materials. */
void ResetFrom(const FManagedArrayCollection& InCollection, const TArray<UMaterial*>& InMaterials, bool bHasInternalMaterials);
int32 AppendGeometry(const UGeometryCollection & Element, bool ReindexAllMaterials = false, const FTransform& TransformRoot = FTransform::Identity);
int32 NumElements(const FName& Group) const;
void RemoveElements(const FName& Group, const TArray<int32>& SortedDeletionList);
/** Has data for static mesh rendering. */
bool HasMeshData() const;
/** Has data for nanite rendering. */
bool HasNaniteData() const;
uint32 GetNaniteResourceID() const;
uint32 GetNaniteHierarchyOffset() const;
uint32 GetNaniteHierarchyOffset(int32 GeometryIndex, bool bFlattened = false) const;
/** ReindexMaterialSections */
void ReindexMaterialSections();
/** appends the standard materials to this UObject */
void InitializeMaterials(bool bHasLegacyInternalMaterialsPairs = false);
/** Add a material to the materials array and update the selected bone material to be at the end of the array */
int32 AddNewMaterialSlot(bool bCopyLastMaterial = true);
/** Remove a material from the materials array, keeping the selected bone material at the end of the array. Returns false if materials could not be removed (e.g. because there were too few). */
bool RemoveLastMaterialSlot();
/** Returns true if there is anything to render */
bool HasVisibleGeometry() const;
/** Invalidates this collection signaling a structural change and renders any previously recorded caches unable to play with this collection */
void InvalidateCollection();
/** Check to see if Simulation Data requires regeneration */
bool IsSimulationDataDirty() const;
/** Attach a Static Mesh exemplar for embedded geometry, if that mesh has not already been attached. Return the exemplar index. */
int32 AttachEmbeddedGeometryExemplar(const UStaticMesh* Exemplar);
/** Remove embedded geometry exemplars with indices matching the sorted removal list. */
void RemoveExemplars(const TArray<int32>& SortedRemovalIndices);
/** find or add a auto instance mesh and return its index */
const FGeometryCollectionAutoInstanceMesh& GetAutoInstanceMesh(int32 AutoInstanceMeshIndex) const;
/** find or add a auto instance mesh from another one and return its index */
int32 FindOrAddAutoInstanceMesh(const FGeometryCollectionAutoInstanceMesh& AutoInstanecMesh);
/** find or add a auto instance mesh from a mesh and alist of material and return its index */
int32 FindOrAddAutoInstanceMesh(const UStaticMesh* StaticMesh, const TArray<UMaterialInterface*>& Materials);
/** Produce a deep copy of GeometryCollection member, stripped of data unecessary for gameplay. */
TSharedPtr<FGeometryCollection, ESPMode::ThreadSafe> GenerateMinimalGeometryCollection() const;
/** copy a collection and remove geometry from it */
static TSharedPtr<FGeometryCollection, ESPMode::ThreadSafe> CopyCollectionAndRemoveGeometry(const TSharedPtr<const FGeometryCollection, ESPMode::ThreadSafe>& CollectionToCopy);
#if WITH_EDITOR
/** If this flag is set, we only regenerate simulation data when requested via CreateSimulationData() */
bool bManualDataCreate;
/**
* Create the simulation data that can be shared among all instances (mass, volume, etc...)
* Note : this does not check if the simulation data is drty or not and will cause a load from the DDC
* use CreateSimulationDataIfNeeded() for avoiding extra runtime cost
*/
void CreateSimulationData();
/** Create the simulation data ( calls CreateSimulationData) only if the simulation data is dirty */
void CreateSimulationDataIfNeeded();
/** Rebuild the render data. */
void RebuildRenderData();
/** Propogate render state dirty to components */
void PropagateMarkDirtyToComponents() const;
#endif
void InitResources();
void ReleaseResources();
/** Fills params struct with parameters used for precomputing content. */
void GetSharedSimulationParams(FSharedSimulationParameters& OutParams) const;
/** Accessors for the two guids used to identify this collection */
FGuid GetIdGuid() const;
FGuid GetStateGuid() const;
/** Get the cached root index */
int32 GetRootIndex() const { return RootIndex; }
/** Pointer to the data used to render this geometry collection. */
TUniquePtr<FGeometryCollectionRenderData> RenderData;
UPROPERTY(EditAnywhere, Category = "Clustering")
bool EnableClustering;
/** Maximum level for cluster breaks. */
UPROPERTY(EditAnywhere, Category = "Clustering")
int32 ClusterGroupIndex;
/** Maximum level for cluster breaks. */
UPROPERTY(EditAnywhere, Category = "Clustering")
int32 MaxClusterLevel;
/** Damage threshold for clusters at different levels. */
UPROPERTY(EditAnywhere, Category = "Damage", meta = (EditCondition = "!bUseSizeSpecificDamageThreshold"))
TArray<float> DamageThreshold;
/** whether to use size specific damage threshold instead of level based ones ( see Size Specific Data array ). */
UPROPERTY(EditAnywhere, Category = "Damage")
bool bUseSizeSpecificDamageThreshold;
/** compatibility check, when true, only cluster compute damage from parameters and propagate to direct children
* when false, each child will compute it's damage threshold allowing for more precise and intuitive destruction behavior
*/
UPROPERTY(EditAnywhere, Category = "Compatibility")
bool PerClusterOnlyDamageThreshold;
/** Data about how damage propagation shoudl behave. */
UPROPERTY(EditAnywhere, Category = "Damage")
FGeometryCollectionDamagePropagationData DamagePropagationData;
/** */
UPROPERTY(EditAnywhere, Category = "Clustering")
EClusterConnectionTypeEnum ClusterConnectionType;
UPROPERTY(EditAnywhere, Category = "Clustering")
float ConnectionGraphBoundsFilteringMargin;
#if WITH_EDITORONLY_DATA
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "GeometrySource")
TArray<FGeometryCollectionSource> GeometrySource;
#endif
UPROPERTY(EditAnywhere, Category = "Materials")
TArray<TObjectPtr<UMaterialInterface>> Materials;
/** References for embedded geometry generation */
UPROPERTY(EditAnywhere, Category = "EmbeddedGeometry")
TArray<FGeometryCollectionEmbeddedExemplar> EmbeddedGeometryExemplar;
/** Whether to use full precision UVs when rendering this geometry. (Does not apply to Nanite rendering) */
UPROPERTY(EditAnywhere, Category = "Rendering")
bool bUseFullPrecisionUVs = false;
/**
* Strip unnecessary data from the Geometry Collection to keep the memory footprint as small as possible.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Rendering", meta = (DisplayName = "Strip Source Data On Cook"))
bool bStripOnCook;
/**
* Strip unnecessary render data from the Geometry Collection to keep the memory footprint as small as possible.
* This may be used if the cooked build uses an alternative render path such as ISMPools.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Rendering")
bool bStripRenderDataOnCook;
/** static mesh to use as a proxy for rendering until the geometry collection is broken */
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Rendering")
FGeometryCollectionProxyMeshData RootProxyData;
/** list of unique static mesh / materials pairs for auto instancing*/
UPROPERTY(EditAnywhere, Category = "Rendering")
TArray<FGeometryCollectionAutoInstanceMesh> AutoInstanceMeshes;
/** Array of material custom data for all static meshes in AutoInstanceMeshes. */
UPROPERTY(EditAnywhere, Category = "Rendering")
TArray<float> AutoInstanceMaterialCustomData;
UFUNCTION(BlueprintCallable, Category = "Nanite")
void SetEnableNanite(bool bValue);
/**
* Enable support for Nanite.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, BlueprintSetter=SetEnableNanite, Category = "Nanite")
bool EnableNanite;
#if WITH_EDITORONLY_DATA
/*
* CollisionType defines how to initialize the rigid collision structures.
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
ECollisionTypeEnum CollisionType_DEPRECATED;
/*
* CollisionType defines how to initialize the rigid collision structures.
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
EImplicitTypeEnum ImplicitType_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 5)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
int32 MinLevelSetResolution_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 10)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
int32 MaxLevelSetResolution_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 5)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
int32 MinClusterLevelSetResolution_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 10)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
int32 MaxClusterLevelSetResolution_DEPRECATED;
/*
* Resolution on the smallest axes for the level set. (def: 10)
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
float CollisionObjectReductionPercentage_DEPRECATED;
/** static mesh to use as a proxy for rendering until the geometry collection is broken */
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use RootProxyData instead."))
FSoftObjectPath RootProxy_DEPRECATED;
#endif
/**
* Mass As Density, units are in kg/m^3
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collisions")
bool bMassAsDensity;
/**
* Total Mass of Collection. If density, units are in kg/m^3
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collisions")
float Mass;
/**
* Smallest allowable mass (def:0.1)
*/
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Collisions")
float MinimumMassClamp;
/**
* whether to import collision from the source asset
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Collisions")
bool bImportCollisionFromSource;
#if WITH_EDITORONLY_DATA
/**
* Number of particles on the triangulated surface to use for collisions.
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
float CollisionParticlesFraction_DEPRECATED;
/**
* Max number of particles.
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "This property is deprecated. Use the default SizeSpecificData instead."))
int32 MaximumCollisionParticles_DEPRECATED;
#endif
/** Remove particle from simulation and dissolve rendered geometry once sleep threshold has been exceeded. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Removal, meta = (DisplayName = "Remove on Sleep"))
bool bRemoveOnMaxSleep;
/** How long may the particle sleep before initiating removal (in seconds). */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Removal, meta = (DisplayName = "Sleep Min Max", EditCondition="bRemoveOnMaxSleep"))
FVector2D MaximumSleepTime;
/** How long does the removal process take (in seconds). */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Removal, meta = (DisplayName = "Removal Duration", EditCondition="bRemoveOnMaxSleep"))
FVector2D RemovalDuration;
/** when on non-sleeping, slow moving pieces will be considered as sleeping, this helps removal of jittery but not really moving objects. */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Removal, meta = (DisplayName = "Slow-Moving as sleeping", EditCondition="bRemoveOnMaxSleep"))
bool bSlowMovingAsSleeping;
/** When slow moving detection is on, this defines the linear velocity thresholds in cm/s to consider the object as sleeping . */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Removal, meta = (DisplayName = "Slow-Moving Velocity Threshold", EditCondition="bRemoveOnMaxSleep && bSlowMovingAsSleeping"))
float SlowMovingVelocityThreshold;
/*
* Size Specfic Data reflects the default geometry to bind to rigid bodies smaller
* than the max size volume. This can also be empty to reflect no collision geometry
* for the collection.
*/
UPROPERTY(EditAnywhere, Category = "Collisions")
TArray<FGeometryCollectionSizeSpecificData> SizeSpecificData;
int GetDefaultSizeSpecificDataIndex() const;
FGeometryCollectionSizeSpecificData& GetDefaultSizeSpecificData();
const FGeometryCollectionSizeSpecificData& GetDefaultSizeSpecificData() const;
static FGeometryCollectionSizeSpecificData GeometryCollectionSizeSpecificDataDefaults();
/**
* Enable remove pieces on fracture
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use remove on break feature instead ( Fracture editor tools )."))
bool EnableRemovePiecesOnFracture_DEPRECATED;
/**
* Materials relating to remove on fracture
*/
UPROPERTY(meta = (DeprecatedProperty, DeprecationMessage = "Use remove on break feature instead ( Fracture editor tools )."))
TArray<TObjectPtr<UMaterialInterface>> RemoveOnFractureMaterials_DEPRECATED;
FORCEINLINE const int32 GetBoneSelectedMaterialIndex() const { return BoneSelectedMaterialIndex; }
UMaterialInterface* GetBoneSelectedMaterial() const
{
return BoneSelectedMaterial;
}
/** Returns the asset path for the automatically populated selected material. */
static const TCHAR* GetSelectedMaterialPath();
#if WITH_EDITORONLY_DATA
/** Importing data and options used for this geometry collection */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = ImportSettings)
TObjectPtr<class UAssetImportData> AssetImportData;
/** Information for thumbnail rendering */
UPROPERTY(VisibleAnywhere, Instanced, AdvancedDisplay, Category = GeometryCollection)
TObjectPtr<class UThumbnailInfo> ThumbnailInfo;
#endif // WITH_EDITORONLY_DATA
/*
* Update the convex geometry on the collection.
*/
void UpdateConvexGeometry();
void UpdateConvexGeometryIfMissing();
/*
* Update properties that depend on the geometry and clustering: Proximity, Convex Hulls, Volume and Size data.
*/
void UpdateGeometryDependentProperties();
//~ Begin IInterface_AssetUserData Interface
virtual void AddAssetUserData(UAssetUserData* InUserData) override;
virtual void RemoveUserDataOfClass(TSubclassOf<UAssetUserData> InUserDataClass) override;
virtual UAssetUserData* GetAssetUserDataOfClass(TSubclassOf<UAssetUserData> InUserDataClass) override;
virtual const TArray<UAssetUserData*>* GetAssetUserDataArray() const override;
//~ End IInterface_AssetUserData Interface
//
// Dataflow
//
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Dataflow")
TObjectPtr<UDataflow> DataflowAsset;
UPROPERTY(EditAnywhere, Category = "Dataflow")
FString DataflowTerminal = "GeometryCollectionTerminal";
private:
#if WITH_EDITOR
void CreateSimulationDataImp(bool bCopyFromDDC);
void CreateRenderDataImp(bool bCopyFromDDC);
#endif
/*
* Used to transfer deprecated properties to the size specific structures during serialization
* and to add back the default size specific data when deleted.
*/
void ValidateSizeSpecificDataDefaults();
// update cachedroot index using the current hierarchy setup
void UpdateRootIndex();
private:
/** Guid created on construction of this collection. It should be used to uniquely identify this collection */
UPROPERTY()
FGuid PersistentGuid;
/**
* Guid that can be invalidated on demand - essentially a 'version' that should be changed when a structural change is made to
* the geometry collection. This signals to any caches that attempt to link to a geometry collection whether the collection
* is still valid (hasn't structurally changed post-recording)
*/
UPROPERTY()
FGuid StateGuid;
#if WITH_EDITOR
//Used to determine whether we need to cook simulation data
FGuid LastBuiltSimulationDataGuid;
//Used to determine whether we need to regenerate simulation data
FGuid SimulationDataGuid;
//Used to determine whether we need to cook render data
FGuid LastBuiltRenderDataGuid;
//Used to determine whether we need to regenerate render data
FGuid RenderDataGuid;
#endif
// cached root index for faster queries
UPROPERTY(VisibleAnywhere, Category = "Clustering")
int32 RootIndex = INDEX_NONE;
// #todo(dmp): rename to be consistent BoneSelectedMaterialID?
// Legacy index of the bone selected material in the object's Materials array, or INDEX_NONE if it is not stored there.
// Note for new objects the bone selected material should not be stored in the Materials array, so this should be INDEX_NONE
UPROPERTY()
int32 BoneSelectedMaterialIndex = INDEX_NONE;
// The material to use for rendering bone selections in the editor, or nullptr
UPROPERTY()
TObjectPtr<UMaterialInterface> BoneSelectedMaterial = nullptr;
TSharedPtr<FGeometryCollection, ESPMode::ThreadSafe> GeometryCollection;
/** Array of user data stored with the asset */
UPROPERTY(EditAnywhere, AdvancedDisplay, Instanced, Category = AssetUserData)
TArray<TObjectPtr<UAssetUserData>> AssetUserData;
};