94 lines
4.3 KiB
C++
94 lines
4.3 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Dataflow/DataflowEngine.h"
|
|
#include "GeometryCollection/ManagedArrayCollection.h"
|
|
#include "Engine/StaticMesh.h"
|
|
#include "Engine/SkeletalMesh.h"
|
|
#include "Dataflow/DataflowSelection.h"
|
|
#include "ChaosFleshGenerateSurfaceBindingsNode.generated.h"
|
|
|
|
class UStaticMesh;
|
|
class USkeletalMesh;
|
|
class UDynamicMesh;
|
|
|
|
DECLARE_LOG_CATEGORY_EXTERN(LogMeshBindings, Verbose, All);
|
|
|
|
/* Generate barycentric bindings (used by the FleshDeformer deformer graph and Geometry Cache generation) of a render surface to a tetrahedral mesh.
|
|
* If a point is outside of the tetrahedral mesh, find surface embedding within SurfaceProjectionSearchRadius.
|
|
Embeddings are color coded in the render view:
|
|
green: embedded on in a tetrahedron
|
|
blue: embedded on a surface triangle
|
|
red: orphan (cannot be embedded)
|
|
yellow: orphan reparented to a tetrahedron from a node neighbor */
|
|
USTRUCT(meta = (DataflowFlesh))
|
|
struct FGenerateSurfaceBindings : public FDataflowNode
|
|
{
|
|
GENERATED_USTRUCT_BODY()
|
|
DATAFLOW_NODE_DEFINE_INTERNAL(FGenerateSurfaceBindings, "GenerateSurfaceBindings", "Flesh", "")
|
|
DATAFLOW_NODE_RENDER_TYPE("SurfaceRender", FName("FDynamicMesh3"), "SKMDynamicMesh")
|
|
|
|
public:
|
|
FGenerateSurfaceBindings(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
|
|
: FDataflowNode(InParam, InGuid)
|
|
{
|
|
RegisterInputConnection(&Collection);
|
|
RegisterOutputConnection(&Collection, &Collection);
|
|
RegisterInputConnection(&StaticMeshIn);
|
|
RegisterInputConnection(&SkeletalMeshIn);
|
|
RegisterInputConnection(&TransformSelection)
|
|
.SetCanHidePin(true)
|
|
.SetPinIsHidden(true);
|
|
RegisterInputConnection(&GeometryGroupGuidsIn)
|
|
.SetCanHidePin(true)
|
|
.SetPinIsHidden(true);
|
|
RegisterOutputConnection(&SKMDynamicMesh)
|
|
.SetCanHidePin(true)
|
|
.SetPinIsHidden(true);
|
|
}
|
|
|
|
private:
|
|
/** Passthrough geometry collection. Bindings are stored as standalone groups in the \p Collection, keyed by the name of the input render mesh and all available LOD's. */
|
|
UPROPERTY(meta = (DataflowInput, DataflowOutput, DataflowPassthrough = "Collection", DisplayName = "Collection"))
|
|
FManagedArrayCollection Collection;
|
|
|
|
/** The input mesh, whose render surface is used to generate bindings. */
|
|
UPROPERTY(EditAnywhere, Category = "Dataflow", DisplayName = "Static Mesh", meta = (DataflowInput, EditCondition = "SkeletalMeshIn == nullptr"))
|
|
TObjectPtr<const UStaticMesh> StaticMeshIn = nullptr;
|
|
|
|
/** The input mesh, whose render surface is used to generate bindings. */
|
|
UPROPERTY(EditAnywhere, Category = "Dataflow", DisplayName = "Skeletal Mesh", meta = (DataflowInput, EditCondition = "StaticMeshIn == nullptr"))
|
|
TObjectPtr<const USkeletalMesh> SkeletalMeshIn = nullptr;
|
|
|
|
/** Only meshes with transforms in TransformSelection will be bound. */
|
|
UPROPERTY(meta = (DataflowInput, DisplayName = "(Optional) TransformSelection"))
|
|
FDataflowTransformSelection TransformSelection;
|
|
|
|
/** Only meshes with transforms in TransformSelection will be bound. */
|
|
UPROPERTY(meta = (DataflowInput, DisplayName = "(Optional) GeometryGroupGuids"))
|
|
TArray<FString> GeometryGroupGuidsIn;
|
|
|
|
/** Use the import geometry of the skeletal mesh. */
|
|
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (DisplayName = "UseSkeletalMeshImportModel", EditCondition = "SkeletalMeshIn != nullptr"))
|
|
bool bUseSkeletalMeshImportModel = false;
|
|
|
|
/** Enable binding to the exterior hull of the tetrahedron mesh. */
|
|
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (DisplayName = "DoSurfaceProjection"))
|
|
bool bDoSurfaceProjection = true;
|
|
|
|
/** The search radius when looking for surface triangles to bind to. */
|
|
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (DisplayName = "SurfaceProjectionSearchRadius", EditCondition = "bDoSurfaceProjection == true"))
|
|
float SurfaceProjectionSearchRadius = 1.f;
|
|
|
|
/** When nodes aren't contained in tetrahedra and surface projection fails, try to find suitable bindings by looking to neighboring parents. */
|
|
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (DisplayName = "DoOrphanReparenting"))
|
|
bool bDoOrphanReparenting = true;
|
|
|
|
/** Converted from embedded skeletal/static mesh */
|
|
UPROPERTY(meta = (DataflowOutput))
|
|
TObjectPtr<UDynamicMesh> SKMDynamicMesh;
|
|
|
|
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
|
|
}; |