|
| 1 | +// Copyright 2025 Timothé Lapetite and contributors |
| 2 | +// Released under the MIT license https://opensource.org/license/MIT/ |
| 3 | + |
| 4 | +#pragma once |
| 5 | + |
| 6 | +#include "CoreMinimal.h" |
| 7 | +#include "PCGExGlobalSettings.h" |
| 8 | + |
| 9 | +#include "PCGExPointsProcessor.h" |
| 10 | +#include "PCGExTransform.h" |
| 11 | +#include "Data/Matching/PCGExMatching.h" |
| 12 | + |
| 13 | + |
| 14 | +#include "PCGExBestMatchAxis.generated.h" |
| 15 | + |
| 16 | +class FPCGExComputeIOBounds; |
| 17 | + |
| 18 | +UENUM() |
| 19 | +enum class EPCGExBestMatchAxisTargetMode : uint8 |
| 20 | +{ |
| 21 | + Direction = 0 UMETA(DisplayName = "Direction", ToolTip="Best match against a direction vector."), |
| 22 | + LookAtWorldPosition = 1 UMETA(DisplayName = "Look at Position (World)", ToolTip="Best match against the look at vector toward a world position."), |
| 23 | + LookAtRelativePosition = 2 UMETA(DisplayName = "Look at Position (Relative)", ToolTip="Best match against the look at vector toward a relative position."), |
| 24 | + ClosestTarget = 3 UMETA(DisplayName = "Look at Closest Target", ToolTip="Best match against the look at vector toward the closest target point.") |
| 25 | +}; |
| 26 | + |
| 27 | +UCLASS(Hidden, BlueprintType, ClassGroup = (Procedural), Category="PCGEx|Misc", meta=(PCGExNodeLibraryDoc="transform/move-pivot")) |
| 28 | +class UPCGExBestMatchAxisSettings : public UPCGExPointsProcessorSettings |
| 29 | +{ |
| 30 | + GENERATED_BODY() |
| 31 | + |
| 32 | +public: |
| 33 | + //~Begin UPCGSettings |
| 34 | +#if WITH_EDITOR |
| 35 | + PCGEX_NODE_INFOS(BestMatchAxis, "Best Match Axis", "Rotate a point or transform to closely match an input direction (or look at location) but preserve orthogonality."); |
| 36 | + virtual FLinearColor GetNodeTitleColor() const override { return GetDefault<UPCGExGlobalSettings>()->NodeColorTransform; } |
| 37 | +#endif |
| 38 | + |
| 39 | +protected: |
| 40 | + virtual TArray<FPCGPinProperties> InputPinProperties() const override; |
| 41 | + virtual FPCGElementPtr CreateElement() const override; |
| 42 | + //~End UPCGSettings |
| 43 | + |
| 44 | +public: |
| 45 | + |
| 46 | + /** Drive the best match axis */ |
| 47 | + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable)) |
| 48 | + EPCGExBestMatchAxisTargetMode Mode = EPCGExBestMatchAxisTargetMode::Direction; |
| 49 | + |
| 50 | + |
| 51 | + /** Up vector source.*/ |
| 52 | + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, EditCondition="Mode != EPCGExBestMatchAxisTargetMode::ClosestTarget", EditConditionHides)) |
| 53 | + EPCGExInputValueType MatchInput = EPCGExInputValueType::Attribute; |
| 54 | + |
| 55 | + /** The attribute or property on selected source to use as Up vector for the look at transform.*/ |
| 56 | + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, DisplayName=" └─ Match (Attr)", EditCondition="Mode != EPCGExBestMatchAxisTargetMode::ClosestTarget && MatchInput != EPCGExInputValueType::Constant", EditConditionHides)) |
| 57 | + FPCGAttributePropertyInputSelector MatchSource; |
| 58 | + |
| 59 | + /** The constant to use as Up vector for the look at transform.*/ |
| 60 | + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, DisplayName=" └─ Match", EditCondition="Mode != EPCGExBestMatchAxisTargetMode::ClosestTarget && MatchInput == EPCGExInputValueType::Constant", EditConditionHides)) |
| 61 | + FVector MatchConstant = FVector::UpVector; |
| 62 | + |
| 63 | + PCGEX_SETTING_VALUE_GET(Match, FVector, MatchInput, MatchSource, MatchConstant) |
| 64 | + |
| 65 | + // TODO : Support attribute mutation such as transform, rotator, vector |
| 66 | + // TODO : Auto-pick axis based on unsigned dot product (so we only mutate where it make the most meaingful) |
| 67 | + |
| 68 | + /** If enabled, allows you to filter out which targets get sampled by which data */ |
| 69 | + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, EditCondition="Mode == EPCGExBestMatchAxisTargetMode::ClosestTarget", EditConditionHides)) |
| 70 | + FPCGExMatchingDetails DataMatching = FPCGExMatchingDetails(EPCGExMatchingDetailsUsage::Sampling); |
| 71 | + |
| 72 | + /** Distance method to be used for source & target points. */ |
| 73 | + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, EditCondition="Mode == EPCGExBestMatchAxisTargetMode::ClosestTarget", EditConditionHides)) |
| 74 | + FPCGExDistanceDetails DistanceDetails; |
| 75 | + |
| 76 | +private: |
| 77 | + friend class FPCGExBestMatchAxisElement; |
| 78 | +}; |
| 79 | + |
| 80 | +struct FPCGExBestMatchAxisContext final : FPCGExPointsProcessorContext |
| 81 | +{ |
| 82 | + friend class FPCGExBestMatchAxisElement; |
| 83 | + |
| 84 | + TSharedPtr<PCGExSampling::FTargetsHandler> TargetsHandler; |
| 85 | + int32 NumMaxTargets = 0; |
| 86 | + |
| 87 | +protected: |
| 88 | + PCGEX_ELEMENT_BATCH_POINT_DECL |
| 89 | +}; |
| 90 | + |
| 91 | +class FPCGExBestMatchAxisElement final : public FPCGExPointsProcessorElement |
| 92 | +{ |
| 93 | +protected: |
| 94 | + PCGEX_ELEMENT_CREATE_CONTEXT(BestMatchAxis) |
| 95 | + |
| 96 | + virtual bool Boot(FPCGExContext* InContext) const override; |
| 97 | + virtual bool ExecuteInternal(FPCGContext* Context) const override; |
| 98 | +}; |
| 99 | + |
| 100 | +namespace PCGExBestMatchAxis |
| 101 | +{ |
| 102 | + class FProcessor final : public PCGExPointsMT::TProcessor<FPCGExBestMatchAxisContext, UPCGExBestMatchAxisSettings> |
| 103 | + { |
| 104 | + TSet<const UPCGData*> IgnoreList; |
| 105 | + TSharedPtr<PCGExDetails::TSettingValue<FVector>> MatchGetter; |
| 106 | + |
| 107 | + public: |
| 108 | + explicit FProcessor(const TSharedRef<PCGExData::FFacade>& InPointDataFacade): |
| 109 | + TProcessor(InPointDataFacade) |
| 110 | + { |
| 111 | + } |
| 112 | + |
| 113 | + virtual ~FProcessor() override; |
| 114 | + |
| 115 | + virtual bool Process(const TSharedPtr<PCGExMT::FTaskManager>& InAsyncManager) override; |
| 116 | + virtual void ProcessPoints(const PCGExMT::FScope& Scope) override; |
| 117 | + }; |
| 118 | +} |
0 commit comments