Files
Brandyn / Techy fcc1b09210 init
2026-04-04 15:40:51 -05:00

148 lines
4.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Retargeter/IKRetargetOps.h"
#include "Retargeter/IKRetargetSettings.h"
#include "BodyIntersectIKOp.generated.h"
#define UE_API BODYINTERSECTIKOP_API
#define LOCTEXT_NAMESPACE "BodyIntersectIKOp"
struct FIKRigGoal;
struct FKShapeElem;
class UPhysicsAsset;
// Used to hold all debug draw info for convenience
struct FDebugBodyIntersectDrawInfo
{
// Intersect info
TArray<TTuple<FName,FTransform>> TargetIntersectTfms;
TArray<TTuple<FVector,double>> TestSpheres;
};
USTRUCT(BlueprintType, meta = (DisplayName = "Body Intersect IK Settings"))
struct FIKRetargetBodyIntersectIKOpSettings : public FIKRetargetOpSettingsBase
{
GENERATED_BODY()
UE_API virtual const UClass* GetControllerType() const override;
UE_API virtual void CopySettingsAtRuntime(const FIKRetargetOpSettingsBase* InSettingsToCopyFrom) override;
// Target physics asset for checking intersections against
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Physics", meta=(ReinitializeOnEdit))
TObjectPtr<UPhysicsAsset> TargetPhysicsAssetOverride;
// IK Goals to check sphere intersections (Goal effector bone should have a sphere or capsule body!)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Intersection", meta=(ReinitializeOnEdit))
TArray<FName> IntersectGoals;
// Physics bodies to do trivial intersection against
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Intersection", meta=(ReinitializeOnEdit))
TArray<FName> IntersectBodies;
};
USTRUCT(BlueprintType, meta = (DisplayName = "Body Intersect Goals"))
struct FIKRetargetBodyIntersectIKOp : public FIKRetargetOpBase
{
GENERATED_BODY()
UE_API virtual bool Initialize(
const FIKRetargetProcessor& InProcessor,
const FRetargetSkeleton& InSourceSkeleton,
const FTargetSkeleton& InTargetSkeleton,
const FIKRetargetOpBase* InParentOp,
FIKRigLogger& InLog) override;
UE_API virtual void Run(
FIKRetargetProcessor& InProcessor,
const double InDeltaTime,
const TArray<FTransform>& InSourceGlobalPose,
TArray<FTransform>& OutTargetGlobalPose) override;
UE_API virtual void OnAddedToStack(const UIKRetargeter* InRetargetAsset, const FIKRetargetOpBase* InParentOp) override;
UE_API virtual FIKRetargetOpSettingsBase* GetSettings() override;
UE_API virtual const UScriptStruct* GetSettingsType() const override;
UE_API virtual const UScriptStruct* GetType() const override;
UE_API virtual const UScriptStruct* GetParentOpType() const override;
UPROPERTY()
FIKRetargetBodyIntersectIKOpSettings Settings;
private:
void UpdateCacheSkelInfo(const FTargetSkeleton& InTargetSkeleton);
void UpdateTargetBoneMap(FName TargetBoneName);
FVector GoalLocBlendCompSpace(const FIKRigGoal* Goal, const FTransform& BoneTfm) const;
void SetGoalPosFromCompSpace(FIKRigGoal* Goal, const FTransform& BoneTfm, const FVector& CompSpaceLoc) const;
static double CalcIntersectionDelta(const FVector& TargetPoint, double TargetRadius, const FTransform& ShapeTfm, FKShapeElem* ShapeElem, FVector& OutDeltaDir);
static double CalcShapeSmallRadius(FKShapeElem* ShapeElem);
static double CalcShapeAvgRadius(FKShapeElem* ShapeElem);
static FKShapeElem* FindBodyShape(const UPhysicsAsset* PhysAsset, FName BoneName);
#if WITH_EDITOR
public:
UE_API virtual void DebugDraw(
FPrimitiveDrawInterface* InPDI,
const FTransform& InSourceTransform,
const FTransform& InComponentTransform,
const double InComponentScale,
const FIKRetargetDebugDrawState& InEditorState) const override;
UE_API virtual bool HasDebugDrawing() override { return true; };
private:
void DebugDrawPhysBody(FPrimitiveDrawInterface* InPDI, const FTransform& ParentTransform, double Scale, const FKShapeElem* ShapeElem, const FLinearColor& Color) const;
void ResetDebugInfo();
// Collection of all debug structures
FDebugBodyIntersectDrawInfo DebugDrawInfo;
static UE_API FCriticalSection DebugDataMutex;
#endif
private:
TObjectPtr<const UPhysicsAsset> PhysicsAsset;
// Cache ik goals to check
TArray<const FIKRigGoal*> IntersectIKGoals;
// Cache source/target bone-names
TArray<FName> TargetBoneNames;
// Cache target skel index info
TMap<FName,int32> CacheTargetSkelIndices;
};
/* The blueprint/python API for editing BodyIntersectIK Op */
UCLASS(MinimalAPI, BlueprintType)
class UIKRetargetBodyIntersectController : public UIKRetargetOpControllerBase
{
GENERATED_BODY()
public:
/* Get the current op settings as a struct.
* @return FIKRetargetBodyIntersectIKOp struct with the current settings used by the op. */
UFUNCTION(BlueprintCallable, Category = Settings)
UE_API FIKRetargetBodyIntersectIKOpSettings GetSettings();
/* Set the solver settings. Input is a custom struct type for this solver.
* @param InSettings a FIKRetargetBodyIntersectIKOp struct containing all the settings to apply to this op */
UFUNCTION(BlueprintCallable, Category = Settings)
UE_API void SetSettings(FIKRetargetBodyIntersectIKOpSettings InSettings);
};
#undef LOCTEXT_NAMESPACE
#undef UE_API