Files
2025-05-18 13:04:45 +08:00

286 lines
13 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Chaos/BoundingVolumeHierarchy.h"
#include "Dataflow/DataflowNode.h"
#include "Dataflow/DataflowConnectionTypes.h"
#include "GeometryCollection/GeometryCollection.h"
#include "Dataflow/DataflowSelection.h"
#include "GeometryCollectionTransferVertexAttributeNode.generated.h"
#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_5
namespace Dataflow = UE::Dataflow;
#else
namespace UE_DEPRECATED(5.5, "Use UE::Dataflow instead.") Dataflow {}
#endif
UENUM(BlueprintType)
enum class EDataflowTransferVertexAttributeNodeFalloff : uint8
{
/** Squared falloff based on distance from triangle*/
Squared UMETA(DisplayName = "Squared"),
/** Linear falloff based on distance from triangle*/
Linear UMETA(DisplayName = "Linear"),
/** No distance falloff */
None UMETA(DisplayName = "None"),
//~~~
//256th entry
Dataflow_Max UMETA(Hidden)
};
UENUM(BlueprintType)
enum class EDataflowTransferVertexAttributeNodeSourceScale : uint8
{
/** Bounding volume hierarchy cell size based on max edge length of each geometry group.
Only works if there is 1-1 correspondence between source and target geometries, otherwise default to Asset Max Edge*/
Component_Edge UMETA(DisplayName = "Component Max Edge"),
/** Bounding volume hierarchy cell size based on max edge length of the whole asset*/
Asset_Edge UMETA(DisplayName = "Asset Max Edge"),
/** Bounding volume hierarchy cell size based on max length of the bounding box of the whole asset*/
Asset_Bound UMETA(DisplayName = "Asset Max Bound"),
//~~~
//256th entry
Dataflow_Max UMETA(Hidden)
};
UENUM(BlueprintType)
enum class EDataflowTransferVertexAttributeNodeBoundingVolume : uint8
{
/** Bounding volume on vertices of the source mesh*/
Vertex UMETA(DisplayName = "Vertex"),
/** Bounding volume on triangles of the source triangle mesh*/
Triangle UMETA(DisplayName = "Triangle"),
//~~~
//256th entry
Dataflow_Max UMETA(Hidden)
};
UENUM(BlueprintType)
enum class EDataflowTransferVertexAttributeNodeTransferMethod : uint8
{
/** Transfers vertex attribute between matched geometries.*/
Component UMETA(DisplayName = "Paired Geometry Transfer"),
/** Transfers vertex attribute globally. Warning: attributes on one geometry might bleed over to neighbor geometries.*/
Global UMETA(DisplayName = "Global Transfer"),
/** No distance falloff */
None UMETA(DisplayName = "None"),
//~~~
//256th entry
Dataflow_Max UMETA(Hidden)
};
/**
* Transfer float properties from a source collection to a target collection.
* Component Transfer is used when all geometries from the source collection have matched names with the target collection.
* Otherwise, Global Transfer is used.
* Geometries are matched when the geometry's BoneName can be found as the start of the BoneName of a geometry in the target collection.
* Use TransformNameSuffix to add extra string to the source geometry's BoneName to avoid multiple matched names.
* For example, source geometry has name SK_10 and target geometry has name SK_10_tet1
* For all names, Check BoneName attribute in Transform group in the collection.
*/
USTRUCT(meta = (DataflowGeometryCollection))
struct FGeometryCollectionTransferVertexAttributeNode : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FGeometryCollectionTransferVertexAttributeNode, "TransferVertexAttribute", "GeometryCollection", "Transfer a named vertex attribute from the Source Collection to the Target Collection")
DATAFLOW_NODE_RENDER_TYPE("SurfaceWeightsRender", FGeometryCollection::StaticType(), "Collection", "AttributeKey")
public:
/* Target collection to transfer vertex attribute to. */
UPROPERTY(Meta = (DataflowInput, DataflowOutput, DataflowPassthrough = "Collection"))
FManagedArrayCollection Collection;
/* Source collection to transfer vertex attribute from. */
UPROPERTY(Meta = (DataflowInput, DisplayName = "FromCollection"))
FManagedArrayCollection FromCollection;
/* The name of the vertex attribute to generate indices from. */
UPROPERTY(EditAnywhere, Category = "Dataflow", Meta = (DataflowInput, DataflowOutput, DisplayName = "AttributeKey", DataflowPassthrough = "AttributeKey"))
FCollectionAttributeKey AttributeKey = FCollectionAttributeKey(FString(""), FString("Vertices"));
/* Transfer method [default: Paired Geometry Transfer] */
UPROPERTY(EditAnywhere, Category = "Method")
EDataflowTransferVertexAttributeNodeTransferMethod TransferMethod = EDataflowTransferVertexAttributeNodeTransferMethod::Component;
/* Bounding volume type for source assets[default: Triangle] */
UPROPERTY(EditAnywhere, Category = "Thresholds")
EDataflowTransferVertexAttributeNodeBoundingVolume BoundingVolumeType = EDataflowTransferVertexAttributeNodeBoundingVolume::Triangle;
/* Bounding volume hierarchy cell size for neighboring vertices to transfer into[default: Asset] */
UPROPERTY(EditAnywhere, Category = "Thresholds")
EDataflowTransferVertexAttributeNodeSourceScale SourceScale = EDataflowTransferVertexAttributeNodeSourceScale::Asset_Bound;
/* Falloff of source value based on distance from source triangle[default: Squared] */
UPROPERTY(EditAnywhere, Category = "Thresholds", meta = (EditCondition = "BoundingVolumeType == EDataflowTransferVertexAttributeNodeBoundingVolume::Triangle", EditConditionHides))
EDataflowTransferVertexAttributeNodeFalloff Falloff = EDataflowTransferVertexAttributeNodeFalloff::None;
/* Threshold based on distance from source triangle.Values past the threshold will falloff.[Defaults to 1 percent of triangle size(0.01)] */
UPROPERTY(EditAnywhere, Category = "Thresholds", meta = (EditCondition =
"Falloff != EDataflowTransferVertexAttributeNodeFalloff::None"
, EditConditionHides))
float FalloffThreshold = 0.01f;
/* Edge multiplier for the Bounding Volume Hierarchy(BVH) target's particle search radius. */
UPROPERTY(EditAnywhere, Category = "Thresholds", meta = (EditCondition = "SourceScale == EDataflowTransferVertexAttributeNodeSourceScale::Asset_Edge || SourceScale == EDataflowTransferVertexAttributeNodeSourceScale::Component_Edge", EditConditionHides))
float EdgeMultiplier = 0.5f;
/* Max bound multiplier for the Bounding Volume Hierarchy(BVH) target's particle search radius. */
UPROPERTY(EditAnywhere, Category = "Thresholds", meta = (
EditCondition = "SourceScale == EDataflowTransferVertexAttributeNodeSourceScale::Asset_Bound",
EditConditionHides))
float BoundMultiplier = 0.01f;
/* Suffix of transform names added to the source geometry's BoneName for geometry matching during transfer[default: _Tet]. In CreateTetrahedron node we add _Tet to tetrahedral geometries.*/
UPROPERTY(EditAnywhere, Category = "Paired Geometry Transfer", meta = (
EditCondition = "TransferMethod == EDataflowTransferVertexAttributeNodeTransferMethod::Component",
EditConditionHides))
FString TransformNameSuffix = "_Tet";
FGeometryCollectionTransferVertexAttributeNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&Collection);
RegisterInputConnection(&FromCollection);
RegisterInputConnection(&AttributeKey);
RegisterOutputConnection(&Collection, &Collection);
RegisterOutputConnection(&AttributeKey, &AttributeKey);
}
private:
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
};
/**
* Transfer skin weights from a source collection to a target collection.
* Component Transfer is used when all geometries from the source collection have matched names with the target collection.
* Otherwise, Global Transfer is used.
* Geometries are matched when the geometry's BoneName can be found as the start of the BoneName of a geometry in the target collection.
* Use TransformNameSuffix to add extra string to the source geometry's BoneName to avoid multiple matched names.
* For example, source geometry has name SK_10 and target geometry has name SK_10_tet1
* For all names, Check BoneName attribute in Transform group in the collection.
*/
USTRUCT(meta = (DataflowGeometryCollection))
struct FGeometryCollectionTransferVertexSkinWeightsNode : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FGeometryCollectionTransferVertexSkinWeightsNode, "TransferVertexSkinWeights", "GeometryCollection", "Transfer vertex skin weights from the Source Collection to the Target Collection")
DATAFLOW_NODE_RENDER_TYPE("SurfaceRender", FGeometryCollection::StaticType(), "Collection")
public:
/* Target collection to transfer vertex attribute to. */
UPROPERTY(Meta = (DataflowInput, DataflowOutput, DataflowPassthrough = "Collection"))
FManagedArrayCollection Collection;
/* Source collection to transfer vertex attribute from. */
UPROPERTY(Meta = (DataflowInput, DisplayName = "FromCollection"))
FManagedArrayCollection FromCollection;
/* Transfer method [default: Paired Geometry Transfer] */
UPROPERTY(EditAnywhere, Category = "Method")
EDataflowTransferVertexAttributeNodeTransferMethod TransferMethod = EDataflowTransferVertexAttributeNodeTransferMethod::Component;
/* Bounding volume type for source assets[default: Triangle] */
UPROPERTY(EditAnywhere, Category = "Thresholds")
EDataflowTransferVertexAttributeNodeBoundingVolume BoundingVolumeType = EDataflowTransferVertexAttributeNodeBoundingVolume::Triangle;
/* Bounding volume hierarchy cell size for neighboring vertices to transfer into[default: Asset] */
UPROPERTY(EditAnywhere, Category = "Thresholds")
EDataflowTransferVertexAttributeNodeSourceScale SourceScale = EDataflowTransferVertexAttributeNodeSourceScale::Asset_Bound;
/* Falloff of source value based on distance from source triangle[default: Squared] */
UPROPERTY(EditAnywhere, Category = "Thresholds", meta = (EditCondition = "BoundingVolumeType == EDataflowTransferVertexAttributeNodeBoundingVolume::Triangle", EditConditionHides))
EDataflowTransferVertexAttributeNodeFalloff Falloff = EDataflowTransferVertexAttributeNodeFalloff::None;
/* Threshold based on distance from source triangle.Values past the threshold will falloff.[Defaults to 1 percent of triangle size(0.01)] */
UPROPERTY(EditAnywhere, Category = "Thresholds", meta = (EditCondition = "Falloff != EDataflowTransferVertexAttributeNodeFalloff::None", EditConditionHides))
float FalloffThreshold = 0.01f;
/* Edge multiplier for the Bounding Volume Hierarchy(BVH) target's particle search radius. */
UPROPERTY(EditAnywhere, Category = "Thresholds", meta = (EditCondition = "SourceScale == EDataflowTransferVertexAttributeNodeSourceScale::Asset_Edge || SourceScale == EDataflowTransferVertexAttributeNodeSourceScale::Component_Edge", EditConditionHides))
float EdgeMultiplier = 0.5f;
/* Max bound multiplier for the Bounding Volume Hierarchy(BVH) target's particle search radius. */
UPROPERTY(EditAnywhere, Category = "Thresholds", meta = (
EditCondition = "SourceScale == EDataflowTransferVertexAttributeNodeSourceScale::Asset_Bound",
EditConditionHides))
float BoundMultiplier = 0.01f;
/* Suffix of transform names for geometry matching during transfer[default: _Tet]. In CreateTetrahedron node we add _Tet to tetrahedral geometries.*/
UPROPERTY(EditAnywhere, Category = "Paired Geometry Transfer", meta = (
EditCondition = "TransferMethod == EDataflowTransferVertexAttributeNodeTransferMethod::Component",
EditConditionHides))
FString TransformNameSuffix = "_Tet";
FGeometryCollectionTransferVertexSkinWeightsNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&Collection);
RegisterInputConnection(&FromCollection);
RegisterOutputConnection(&Collection, &Collection);
}
private:
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
};
UENUM(BlueprintType)
enum class ESetKinematicVertexSelectionKinematicValue : uint8
{
/** Set vertices to be kinematic */
SetKinematic UMETA(DisplayName = "Kinematic"),
/** Set vertices to be dynamic */
SetNonKinematic UMETA(DisplayName = "Non-Kinematic")
};
/**
* Set VertexSelection to be kinematic. Note that kinematic particles need skin weights.
*/
USTRUCT(meta = (DataflowGeometryCollection))
struct FGeometryCollectionSetKinematicVertexSelectionNode : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FGeometryCollectionSetKinematicVertexSelectionNode, "SetKinematicVertexSelection", "GeometryCollection", "Set Vertex Collection to be kinematic")
DATAFLOW_NODE_RENDER_TYPE("SurfaceRender", FGeometryCollection::StaticType(), "Collection")
public:
UPROPERTY(Meta = (DataflowInput, DataflowOutput, DataflowPassthrough = "Collection"))
FManagedArrayCollection Collection;
/** Vertex Selection set to be kinematic */
UPROPERTY(meta = (DataflowInput, DisplayName = "VertexSelection"))
FDataflowVertexSelection VertexSelection;
UPROPERTY(EditAnywhere, Category = "Method", meta = (DisplayName = "VertexSelection"))
ESetKinematicVertexSelectionKinematicValue KinematicValue = ESetKinematicVertexSelectionKinematicValue::SetKinematic;
FGeometryCollectionSetKinematicVertexSelectionNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&Collection);
RegisterInputConnection(&VertexSelection);
RegisterOutputConnection(&Collection, &Collection);
}
private:
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
};