diff --git a/Source/PCGExtendedToolkit/Private/PCGExFitting.cpp b/Source/PCGExtendedToolkit/Private/PCGExFitting.cpp new file mode 100644 index 000000000..1d8affdb5 --- /dev/null +++ b/Source/PCGExtendedToolkit/Private/PCGExFitting.cpp @@ -0,0 +1,308 @@ +// Copyright Timothé Lapetite 2024 +// Released under the MIT license https://opensource.org/license/MIT/ + + +#include "PCGExFitting.h" + +void FPCGExScaleToFitDetails::Process(const FPCGPoint& InPoint, const FBox& InBounds, FVector& OutScale, FBox& OutBounds) const +{ + if (ScaleToFitMode == EPCGExFitMode::None) { return; } + + const FVector PtSize = InPoint.GetLocalBounds().GetSize(); + const FVector ScaledPtSize = InPoint.GetLocalBounds().GetSize() * InPoint.Transform.GetScale3D(); + const FVector StSize = InBounds.GetSize(); + + const double XFactor = ScaledPtSize.X / StSize.X; + const double YFactor = ScaledPtSize.Y / StSize.Y; + const double ZFactor = ScaledPtSize.Z / StSize.Z; + + const FVector FitMinMax = FVector( + FMath::Min3(XFactor, YFactor, ZFactor), + FMath::Max3(XFactor, YFactor, ZFactor), + (XFactor + YFactor + ZFactor) / 3); + + OutBounds.Min = InBounds.Min; + OutBounds.Max = InBounds.Max; + + const FVector InScale = InPoint.Transform.GetScale3D(); + + if (ScaleToFitMode == EPCGExFitMode::Uniform) + { + ScaleToFitAxis(ScaleToFit, 0, InScale, PtSize, StSize, FitMinMax, OutScale); + ScaleToFitAxis(ScaleToFit, 1, InScale, PtSize, StSize, FitMinMax, OutScale); + ScaleToFitAxis(ScaleToFit, 2, InScale, PtSize, StSize, FitMinMax, OutScale); + } + else + { + ScaleToFitAxis(ScaleToFitX, 0, InScale, PtSize, StSize, FitMinMax, OutScale); + ScaleToFitAxis(ScaleToFitY, 1, InScale, PtSize, StSize, FitMinMax, OutScale); + ScaleToFitAxis(ScaleToFitZ, 2, InScale, PtSize, StSize, FitMinMax, OutScale); + } +} + +bool FPCGExSingleJustifyDetails::Init(FPCGExContext* InContext, const TSharedRef& InDataFacade) +{ + if (From == EPCGExJustifyFrom::Custom && FromInput == EPCGExInputValueType::Attribute) + { + FromGetter = InDataFacade->GetScopedBroadcaster(FromSourceAttribute); + if (!FromGetter) + { + if (SharedFromGetter) + { + // No complaints, expected. + } + else + { + PCGE_LOG_C(Warning, GraphAndLog, InContext, FTEXT("Invalid custom 'From' attribute used")); + return false; + } + } + else + { + // Get rid of shared ref + SharedFromGetter = nullptr; + } + } + + if (To == EPCGExJustifyTo::Same) + { + switch (From) + { + default: + case EPCGExJustifyFrom::Min: + To = EPCGExJustifyTo::Min; + break; + case EPCGExJustifyFrom::Center: + To = EPCGExJustifyTo::Center; + break; + case EPCGExJustifyFrom::Max: + To = EPCGExJustifyTo::Max; + break; + case EPCGExJustifyFrom::Custom: + break; + case EPCGExJustifyFrom::Pivot: + To = EPCGExJustifyTo::Pivot; + break; + } + } + + if (To == EPCGExJustifyTo::Custom && FromInput == EPCGExInputValueType::Attribute) + { + ToGetter = InDataFacade->GetScopedBroadcaster(FromSourceAttribute); + if (!ToGetter) + { + if (SharedToGetter) + { + // No complaints, expected. + } + else + { + PCGE_LOG_C(Warning, GraphAndLog, InContext, FTEXT("Invalid custom 'To' attribute used")); + return false; + } + } + else + { + // Get rid of shared ref + SharedToGetter = nullptr; + } + } + + return true; +} + +void FPCGExSingleJustifyDetails::JustifyAxis(const int32 Axis, const int32 Index, const FVector& InCenter, const FVector& InSize, const FVector& OutCenter, const FVector& OutSize, FVector& OutTranslation) const +{ + double Start = 0; + double End = 0; + + const double HalfOutSize = OutSize[Axis] * 0.5; + const double HalfInSize = InSize[Axis] * 0.5; + const double FromValue = SharedFromGetter ? SharedFromGetter->Read(Index)[Axis] : FromGetter ? FromGetter->Read(Index) : FromConstant; + const double ToValue = SharedToGetter ? SharedToGetter->Read(Index)[Axis] : ToGetter ? ToGetter->Read(Index) : ToConstant; + + switch (From) + { + default: + case EPCGExJustifyFrom::Min: + Start = OutCenter[Axis] - HalfOutSize; + break; + case EPCGExJustifyFrom::Center: + Start = OutCenter[Axis]; + break; + case EPCGExJustifyFrom::Max: + Start = OutCenter[Axis] + HalfOutSize; + break; + case EPCGExJustifyFrom::Custom: + Start = OutCenter[Axis] - HalfOutSize + (OutSize[Axis] * FromValue); + break; + case EPCGExJustifyFrom::Pivot: + Start = 0; + break; + } + + switch (To) + { + default: + case EPCGExJustifyTo::Min: + End = InCenter[Axis] - HalfInSize; + break; + case EPCGExJustifyTo::Center: + End = InCenter[Axis]; + break; + case EPCGExJustifyTo::Max: + End = InCenter[Axis] + HalfInSize; + break; + case EPCGExJustifyTo::Custom: + End = InCenter[Axis] - HalfInSize + (InSize[Axis] * ToValue); + break; + case EPCGExJustifyTo::Same: + // == Custom but using From values + End = InCenter[Axis] - HalfInSize * (InSize[Axis] * FromValue); + break; + case EPCGExJustifyTo::Pivot: + End = 0; + break; + } + + OutTranslation[Axis] = End - Start; +} + +void FPCGExJustificationDetails::Process(const int32 Index, const FBox& InBounds, const FBox& OutBounds, FVector& OutTranslation) const +{ + const FVector InCenter = InBounds.GetCenter(); + const FVector InSize = InBounds.GetSize(); + + const FVector OutCenter = OutBounds.GetCenter(); + const FVector OutSize = OutBounds.GetSize(); + + if (bDoJustifyX) { JustifyX.JustifyAxis(0, Index, InCenter, InSize, OutCenter, OutSize, OutTranslation); } + if (bDoJustifyY) { JustifyY.JustifyAxis(1, Index, InCenter, InSize, OutCenter, OutSize, OutTranslation); } + if (bDoJustifyZ) { JustifyZ.JustifyAxis(2, Index, InCenter, InSize, OutCenter, OutSize, OutTranslation); } +} + +bool FPCGExJustificationDetails::Init(FPCGExContext* InContext, const TSharedRef& InDataFacade) +{ + if (bSharedCustomFromAttribute) + { + SharedFromGetter = InDataFacade->GetScopedBroadcaster(CustomFromVectorAttribute); + } + + if (bSharedCustomToAttribute) + { + SharedToGetter = InDataFacade->GetScopedBroadcaster(CustomToVectorAttribute); + } + + if (bDoJustifyX) + { + if (JustifyX.From == EPCGExJustifyFrom::Pivot && (JustifyX.To == EPCGExJustifyTo::Pivot || JustifyX.To == EPCGExJustifyTo::Same)) + { + bDoJustifyX = false; + } + else + { + JustifyX.SharedFromGetter = SharedFromGetter; + JustifyX.SharedToGetter = SharedToGetter; + if (!JustifyX.Init(InContext, InDataFacade)) { return false; } + } + } + + if (bDoJustifyY) + { + if (JustifyY.From == EPCGExJustifyFrom::Pivot && (JustifyY.To == EPCGExJustifyTo::Pivot || JustifyY.To == EPCGExJustifyTo::Same)) + { + bDoJustifyY = false; + } + else + { + JustifyY.SharedFromGetter = SharedFromGetter; + JustifyY.SharedToGetter = SharedToGetter; + if (!JustifyY.Init(InContext, InDataFacade)) { return false; } + } + } + + if (bDoJustifyZ) + { + if (JustifyZ.From == EPCGExJustifyFrom::Pivot && (JustifyZ.To == EPCGExJustifyTo::Pivot || JustifyZ.To == EPCGExJustifyTo::Same)) + { + bDoJustifyZ = false; + } + else + { + JustifyZ.SharedFromGetter = SharedFromGetter; + JustifyZ.SharedToGetter = SharedToGetter; + if (!JustifyZ.Init(InContext, InDataFacade)) { return false; } + } + } + return true; +} + +void FPCGExFittingVariationsDetails::Init(const int InSeed) +{ + Seed = InSeed; + bEnabledBefore = (Offset == EPCGExVariationMode::Before || Rotation != EPCGExVariationMode::Before || Scale != EPCGExVariationMode::Before); + bEnabledAfter = (Offset == EPCGExVariationMode::After || Rotation != EPCGExVariationMode::After || Scale != EPCGExVariationMode::After); +} + +void FPCGExFittingVariationsDetails::Apply(FPCGPoint& InPoint, const FPCGExFittingVariations& Variations, const EPCGExVariationMode& Step) const +{ + FRandomStream RandomSource(PCGExRandom::ComputeSeed(Seed, InPoint.Seed)); + + FVector RandomScale = FVector::OneVector; + FVector RandomOffset = FVector::ZeroVector; + FQuat RandomRotation = FQuat::Identity; + const FTransform SourceTransform = InPoint.Transform; + + if (Offset == Step) + { + const float OffsetX = RandomSource.FRandRange(Variations.OffsetMin.X, Variations.OffsetMax.X); + const float OffsetY = RandomSource.FRandRange(Variations.OffsetMin.Y, Variations.OffsetMax.Y); + const float OffsetZ = RandomSource.FRandRange(Variations.OffsetMin.Z, Variations.OffsetMax.Z); + RandomOffset = FVector(OffsetX, OffsetY, OffsetZ); + } + + if (Rotation == Step) + { + const float RotationX = RandomSource.FRandRange(Variations.RotationMin.Pitch, Variations.RotationMax.Pitch); + const float RotationY = RandomSource.FRandRange(Variations.RotationMin.Yaw, Variations.RotationMax.Yaw); + const float RotationZ = RandomSource.FRandRange(Variations.RotationMin.Roll, Variations.RotationMax.Roll); + RandomRotation = FQuat(FRotator(RotationX, RotationY, RotationZ).Quaternion()); + } + + if (Scale == Step) + { + if (Variations.bUniformScale) + { + RandomScale = FVector(RandomSource.FRandRange(Variations.ScaleMin.X, Variations.ScaleMax.X)); + } + else + { + RandomScale.X = RandomSource.FRandRange(Variations.ScaleMin.X, Variations.ScaleMax.X); + RandomScale.Y = RandomSource.FRandRange(Variations.ScaleMin.Y, Variations.ScaleMax.Y); + RandomScale.Z = RandomSource.FRandRange(Variations.ScaleMin.Z, Variations.ScaleMax.Z); + } + } + + FTransform FinalTransform = SourceTransform; + + if (Variations.bAbsoluteOffset) + { + FinalTransform.SetLocation(SourceTransform.GetLocation() + RandomOffset); + } + else + { + const FTransform RotatedTransform(SourceTransform.GetRotation()); + FinalTransform.SetLocation(SourceTransform.GetLocation() + RotatedTransform.TransformPosition(RandomOffset)); + } + + FinalTransform.SetRotation(SourceTransform.GetRotation() * RandomRotation); + FinalTransform.SetScale3D(SourceTransform.GetScale3D() * RandomScale); + + InPoint.Transform = FinalTransform; +} + +bool FPCGExFittingDetailsHandler::Init(FPCGExContext* InContext, const TSharedRef& InTargetFacade) +{ + TargetDataFacade = InTargetFacade; + return Justification.Init(InContext, InTargetFacade); +} diff --git a/Source/PCGExtendedToolkit/Public/Collections/PCGExAssetCollection.h b/Source/PCGExtendedToolkit/Public/Collections/PCGExAssetCollection.h index 3c4874159..3ccd01d7e 100644 --- a/Source/PCGExtendedToolkit/Public/Collections/PCGExAssetCollection.h +++ b/Source/PCGExtendedToolkit/Public/Collections/PCGExAssetCollection.h @@ -10,7 +10,7 @@ #include "Data/PCGExData.h" #include "Engine/AssetManager.h" #include "Engine/DataAsset.h" -#include "AssetStaging/PCGExFitting.h" +#include "PCGExFitting.h" #include "PCGExAssetCollection.generated.h" diff --git a/Source/PCGExtendedToolkit/Public/Geometry/PCGExGeo.h b/Source/PCGExtendedToolkit/Public/Geometry/PCGExGeo.h index 340fc25d9..cca3f7e7a 100644 --- a/Source/PCGExtendedToolkit/Public/Geometry/PCGExGeo.h +++ b/Source/PCGExtendedToolkit/Public/Geometry/PCGExGeo.h @@ -6,7 +6,7 @@ #include "CoreMinimal.h" #include "PCGEx.h" #include "PCGExMT.h" -#include "AssetStaging/PCGExFitting.h" +#include "PCGExFitting.h" #include "Data/PCGExData.h" diff --git a/Source/PCGExtendedToolkit/Public/Graph/Edges/Refining/PCGExEdgeRefineGabriel.h b/Source/PCGExtendedToolkit/Public/Graph/Edges/Refining/PCGExEdgeRefineGabriel.h index 50a17061c..367e60fe7 100644 --- a/Source/PCGExtendedToolkit/Public/Graph/Edges/Refining/PCGExEdgeRefineGabriel.h +++ b/Source/PCGExtendedToolkit/Public/Graph/Edges/Refining/PCGExEdgeRefineGabriel.h @@ -52,6 +52,4 @@ class /*PCGEXTENDEDTOOLKIT_API*/ UPCGExEdgeRefineGabriel : public UPCGExEdgeRefi }); } -protected: - FPCGExCollisionDetails InitializedCollisionSettings; }; diff --git a/Source/PCGExtendedToolkit/Public/Misc/Filters/PCGExNumericCompareFilter.h b/Source/PCGExtendedToolkit/Public/Misc/Filters/PCGExNumericCompareFilter.h index d537770b2..47cb8de10 100644 --- a/Source/PCGExtendedToolkit/Public/Misc/Filters/PCGExNumericCompareFilter.h +++ b/Source/PCGExtendedToolkit/Public/Misc/Filters/PCGExNumericCompareFilter.h @@ -48,6 +48,7 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExNumericCompareFilterConfig /** Rounding mode for relative measures */ UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, EditCondition="Comparison==EPCGExComparison::NearlyEqual || Comparison==EPCGExComparison::NearlyNotEqual", EditConditionHides)) double Tolerance = DBL_COMPARE_TOLERANCE; + }; diff --git a/Source/PCGExtendedToolkit/Public/Misc/PCGExAttributeRemap.h b/Source/PCGExtendedToolkit/Public/Misc/PCGExAttributeRemap.h index 824ee1848..0d7501d1b 100644 --- a/Source/PCGExtendedToolkit/Public/Misc/PCGExAttributeRemap.h +++ b/Source/PCGExtendedToolkit/Public/Misc/PCGExAttributeRemap.h @@ -14,6 +14,145 @@ #include "PCGExAttributeRemap.generated.h" + +USTRUCT(BlueprintType) +struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExClampDetails +{ + GENERATED_BODY() + + FPCGExClampDetails() + { + } + + FPCGExClampDetails(const FPCGExClampDetails& Other): + bApplyClampMin(Other.bApplyClampMin), + ClampMinValue(Other.ClampMinValue), + bApplyClampMax(Other.bApplyClampMax), + ClampMaxValue(Other.ClampMaxValue) + { + } + + /** Clamp minimum value. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, InlineEditConditionToggle)) + bool bApplyClampMin = false; + + /** Clamp minimum value. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bApplyClampMin")) + double ClampMinValue = 0; + + /** Clamp maximum value. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, InlineEditConditionToggle)) + bool bApplyClampMax = false; + + /** Clamp maximum value. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bApplyClampMax")) + double ClampMaxValue = 0; + + FORCEINLINE double GetClampMin(const double InValue) const { return InValue < ClampMinValue ? ClampMinValue : InValue; } + FORCEINLINE double GetClampMax(const double InValue) const { return InValue > ClampMaxValue ? ClampMaxValue : InValue; } + FORCEINLINE double GetClampMinMax(const double InValue) const { return InValue > ClampMaxValue ? ClampMaxValue : InValue < ClampMinValue ? ClampMinValue : InValue; } + + FORCEINLINE double GetClampedValue(const double InValue) const + { + if (bApplyClampMin && InValue < ClampMinValue) { return ClampMinValue; } + if (bApplyClampMax && InValue > ClampMaxValue) { return ClampMaxValue; } + return InValue; + } +}; + + +USTRUCT(BlueprintType) +struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExRemapDetails +{ + GENERATED_BODY() + + FPCGExRemapDetails() + { + } + + FPCGExRemapDetails(const FPCGExRemapDetails& Other): + bUseAbsoluteRange(Other.bUseAbsoluteRange), + bPreserveSign(Other.bPreserveSign), + bUseInMin(Other.bUseInMin), + InMin(Other.InMin), + CachedInMin(Other.InMin), + bUseInMax(Other.bUseInMax), + InMax(Other.InMax), + CachedInMax(Other.InMax), + RangeMethod(Other.RangeMethod), + Scale(Other.Scale), + RemapCurveObj(Other.RemapCurveObj), + TruncateOutput(Other.TruncateOutput), + PostTruncateScale(Other.PostTruncateScale) + { + } + + ~FPCGExRemapDetails() + { + } + + /** Whether or not to use only positive values to compute range.*/ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable)) + bool bUseAbsoluteRange = true; + + /** Whether or not to preserve value sign when using absolute range.*/ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bUseAbsoluteRange")) + bool bPreserveSign = true; + + /** Fixed In Min value. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, InlineEditConditionToggle)) + bool bUseInMin = false; + + /** Fixed In Min value. If disabled, will use the lowest input value.*/ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bUseInMin")) + double InMin = 0; + double CachedInMin = 0; + + /** Fixed In Max value. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, InlineEditConditionToggle)) + bool bUseInMax = false; + + /** Fixed In Max value. If disabled, will use the highest input value.*/ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bUseInMax")) + double InMax = 0; + double CachedInMax = 0; + + /** How to remap before sampling the curve. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable)) + EPCGExRangeType RangeMethod = EPCGExRangeType::EffectiveRange; + + /** Scale output value. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable)) + double Scale = 1; + + UPROPERTY(EditAnywhere, Category = Settings, BlueprintReadWrite) + TSoftObjectPtr RemapCurve = TSoftObjectPtr(PCGEx::WeightDistributionLinear); + + UPROPERTY(Transient) + TObjectPtr RemapCurveObj = nullptr; + + + /** Whether and how to truncate output value. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable)) + EPCGExTruncateMode TruncateOutput = EPCGExTruncateMode::None; + + /** Scale the value after it's been truncated. */ + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="TruncateOutput != EPCGExTruncateMode::None", EditConditionHides)) + double PostTruncateScale = 1; + + void LoadCurve() + { + PCGEX_LOAD_SOFTOBJECT(UCurveFloat, RemapCurve, RemapCurveObj, PCGEx::WeightDistributionLinear) + } + + FORCEINLINE double GetRemappedValue(const double Value) const + { + return PCGEx::TruncateDbl( + RemapCurveObj->GetFloatValue(PCGExMath::Remap(Value, InMin, InMax, 0, 1)) * Scale, + TruncateOutput); + } +}; + USTRUCT(BlueprintType) struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExComponentRemapRule { diff --git a/Source/PCGExtendedToolkit/Public/PCGExDetails.h b/Source/PCGExtendedToolkit/Public/PCGExDetails.h index 7be949093..23ff38682 100644 --- a/Source/PCGExtendedToolkit/Public/PCGExDetails.h +++ b/Source/PCGExtendedToolkit/Public/PCGExDetails.h @@ -37,143 +37,6 @@ enum class EPCGExSubdivideMode : uint8 Count = 1 UMETA(DisplayName = "Count", ToolTip="Number of subdivisions is fixed"), }; -USTRUCT(BlueprintType) -struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExClampDetails -{ - GENERATED_BODY() - - FPCGExClampDetails() - { - } - - FPCGExClampDetails(const FPCGExClampDetails& Other): - bApplyClampMin(Other.bApplyClampMin), - ClampMinValue(Other.ClampMinValue), - bApplyClampMax(Other.bApplyClampMax), - ClampMaxValue(Other.ClampMaxValue) - { - } - - /** Clamp minimum value. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, InlineEditConditionToggle)) - bool bApplyClampMin = false; - - /** Clamp minimum value. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bApplyClampMin")) - double ClampMinValue = 0; - - /** Clamp maximum value. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, InlineEditConditionToggle)) - bool bApplyClampMax = false; - - /** Clamp maximum value. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bApplyClampMax")) - double ClampMaxValue = 0; - - FORCEINLINE double GetClampMin(const double InValue) const { return InValue < ClampMinValue ? ClampMinValue : InValue; } - FORCEINLINE double GetClampMax(const double InValue) const { return InValue > ClampMaxValue ? ClampMaxValue : InValue; } - FORCEINLINE double GetClampMinMax(const double InValue) const { return InValue > ClampMaxValue ? ClampMaxValue : InValue < ClampMinValue ? ClampMinValue : InValue; } - - FORCEINLINE double GetClampedValue(const double InValue) const - { - if (bApplyClampMin && InValue < ClampMinValue) { return ClampMinValue; } - if (bApplyClampMax && InValue > ClampMaxValue) { return ClampMaxValue; } - return InValue; - } -}; - -USTRUCT(BlueprintType) -struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExRemapDetails -{ - GENERATED_BODY() - - FPCGExRemapDetails() - { - } - - FPCGExRemapDetails(const FPCGExRemapDetails& Other): - bUseAbsoluteRange(Other.bUseAbsoluteRange), - bPreserveSign(Other.bPreserveSign), - bUseInMin(Other.bUseInMin), - InMin(Other.InMin), - CachedInMin(Other.InMin), - bUseInMax(Other.bUseInMax), - InMax(Other.InMax), - CachedInMax(Other.InMax), - RangeMethod(Other.RangeMethod), - Scale(Other.Scale), - RemapCurveObj(Other.RemapCurveObj), - TruncateOutput(Other.TruncateOutput), - PostTruncateScale(Other.PostTruncateScale) - { - } - - ~FPCGExRemapDetails() - { - } - - /** Whether or not to use only positive values to compute range.*/ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable)) - bool bUseAbsoluteRange = true; - - /** Whether or not to preserve value sign when using absolute range.*/ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bUseAbsoluteRange")) - bool bPreserveSign = true; - - /** Fixed In Min value. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, InlineEditConditionToggle)) - bool bUseInMin = false; - - /** Fixed In Min value. If disabled, will use the lowest input value.*/ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bUseInMin")) - double InMin = 0; - double CachedInMin = 0; - - /** Fixed In Max value. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, InlineEditConditionToggle)) - bool bUseInMax = false; - - /** Fixed In Max value. If disabled, will use the highest input value.*/ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="bUseInMax")) - double InMax = 0; - double CachedInMax = 0; - - /** How to remap before sampling the curve. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable)) - EPCGExRangeType RangeMethod = EPCGExRangeType::EffectiveRange; - - /** Scale output value. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable)) - double Scale = 1; - - UPROPERTY(EditAnywhere, Category = Settings, BlueprintReadWrite) - TSoftObjectPtr RemapCurve = TSoftObjectPtr(PCGEx::WeightDistributionLinear); - - UPROPERTY(Transient) - TObjectPtr RemapCurveObj = nullptr; - - - /** Whether and how to truncate output value. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable)) - EPCGExTruncateMode TruncateOutput = EPCGExTruncateMode::None; - - /** Scale the value after it's been truncated. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable, EditCondition="TruncateOutput != EPCGExTruncateMode::None", EditConditionHides)) - double PostTruncateScale = 1; - - void LoadCurve() - { - PCGEX_LOAD_SOFTOBJECT(UCurveFloat, RemapCurve, RemapCurveObj, PCGEx::WeightDistributionLinear) - } - - FORCEINLINE double GetRemappedValue(const double Value) const - { - return PCGEx::TruncateDbl( - RemapCurveObj->GetFloatValue(PCGExMath::Remap(Value, InMin, InMax, 0, 1)) * Scale, - TruncateOutput); - } -}; - namespace PCGExDetails { class /*PCGEXTENDEDTOOLKIT_API*/ FDistances : public TSharedFromThis diff --git a/Source/PCGExtendedToolkit/Public/PCGExFactoryProvider.h b/Source/PCGExtendedToolkit/Public/PCGExFactoryProvider.h index da6cf6053..cebe6a9f5 100644 --- a/Source/PCGExtendedToolkit/Public/PCGExFactoryProvider.h +++ b/Source/PCGExtendedToolkit/Public/PCGExFactoryProvider.h @@ -110,7 +110,7 @@ class /*PCGEXTENDEDTOOLKIT_API*/ UPCGExFactoryProviderSettings : public UPCGSett //~End UPCGExFactoryProviderSettings /** Whether this factory can register consumable attributes or not. */ - UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable), AdvancedDisplay) + UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_NotOverridable), AdvancedDisplay) bool bDoRegisterConsumableAttributes = false; }; diff --git a/Source/PCGExtendedToolkit/Public/AssetStaging/PCGExFitting.h b/Source/PCGExtendedToolkit/Public/PCGExFitting.h similarity index 60% rename from Source/PCGExtendedToolkit/Public/AssetStaging/PCGExFitting.h rename to Source/PCGExtendedToolkit/Public/PCGExFitting.h index 1a534e182..31239296b 100644 --- a/Source/PCGExtendedToolkit/Public/AssetStaging/PCGExFitting.h +++ b/Source/PCGExtendedToolkit/Public/PCGExFitting.h @@ -89,41 +89,7 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExScaleToFitDetails const FPCGPoint& InPoint, const FBox& InBounds, FVector& OutScale, - FBox& OutBounds) const - { - if (ScaleToFitMode == EPCGExFitMode::None) { return; } - - const FVector PtSize = InPoint.GetLocalBounds().GetSize(); - const FVector ScaledPtSize = InPoint.GetLocalBounds().GetSize() * InPoint.Transform.GetScale3D(); - const FVector StSize = InBounds.GetSize(); - - const double XFactor = ScaledPtSize.X / StSize.X; - const double YFactor = ScaledPtSize.Y / StSize.Y; - const double ZFactor = ScaledPtSize.Z / StSize.Z; - - const FVector FitMinMax = FVector( - FMath::Min3(XFactor, YFactor, ZFactor), - FMath::Max3(XFactor, YFactor, ZFactor), - (XFactor + YFactor + ZFactor) / 3); - - OutBounds.Min = InBounds.Min; - OutBounds.Max = InBounds.Max; - - const FVector InScale = InPoint.Transform.GetScale3D(); - - if (ScaleToFitMode == EPCGExFitMode::Uniform) - { - ScaleToFitAxis(ScaleToFit, 0, InScale, PtSize, StSize, FitMinMax, OutScale); - ScaleToFitAxis(ScaleToFit, 1, InScale, PtSize, StSize, FitMinMax, OutScale); - ScaleToFitAxis(ScaleToFit, 2, InScale, PtSize, StSize, FitMinMax, OutScale); - } - else - { - ScaleToFitAxis(ScaleToFitX, 0, InScale, PtSize, StSize, FitMinMax, OutScale); - ScaleToFitAxis(ScaleToFitY, 1, InScale, PtSize, StSize, FitMinMax, OutScale); - ScaleToFitAxis(ScaleToFitZ, 2, InScale, PtSize, StSize, FitMinMax, OutScale); - } - } + FBox& OutBounds) const; private: static void ScaleToFitAxis( @@ -210,76 +176,7 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExSingleJustifyDetails TSharedPtr> ToGetter; TSharedPtr> SharedToGetter; - bool Init(FPCGExContext* InContext, const TSharedRef& InDataFacade) - { - if (From == EPCGExJustifyFrom::Custom && FromInput == EPCGExInputValueType::Attribute) - { - FromGetter = InDataFacade->GetScopedBroadcaster(FromSourceAttribute); - if (!FromGetter) - { - if (SharedFromGetter) - { - // No complaints, expected. - } - else - { - PCGE_LOG_C(Warning, GraphAndLog, InContext, FTEXT("Invalid custom 'From' attribute used")); - return false; - } - } - else - { - // Get rid of shared ref - SharedFromGetter = nullptr; - } - } - - if (To == EPCGExJustifyTo::Same) - { - switch (From) - { - default: - case EPCGExJustifyFrom::Min: - To = EPCGExJustifyTo::Min; - break; - case EPCGExJustifyFrom::Center: - To = EPCGExJustifyTo::Center; - break; - case EPCGExJustifyFrom::Max: - To = EPCGExJustifyTo::Max; - break; - case EPCGExJustifyFrom::Custom: - break; - case EPCGExJustifyFrom::Pivot: - To = EPCGExJustifyTo::Pivot; - break; - } - } - - if (To == EPCGExJustifyTo::Custom && FromInput == EPCGExInputValueType::Attribute) - { - ToGetter = InDataFacade->GetScopedBroadcaster(FromSourceAttribute); - if (!ToGetter) - { - if (SharedToGetter) - { - // No complaints, expected. - } - else - { - PCGE_LOG_C(Warning, GraphAndLog, InContext, FTEXT("Invalid custom 'To' attribute used")); - return false; - } - } - else - { - // Get rid of shared ref - SharedToGetter = nullptr; - } - } - - return true; - } + bool Init(FPCGExContext* InContext, const TSharedRef& InDataFacade); void JustifyAxis( const int32 Axis, @@ -288,62 +185,7 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExSingleJustifyDetails const FVector& InSize, const FVector& OutCenter, const FVector& OutSize, - FVector& OutTranslation) const - { - double Start = 0; - double End = 0; - - const double HalfOutSize = OutSize[Axis] * 0.5; - const double HalfInSize = InSize[Axis] * 0.5; - const double FromValue = SharedFromGetter ? SharedFromGetter->Read(Index)[Axis] : FromGetter ? FromGetter->Read(Index) : FromConstant; - const double ToValue = SharedToGetter ? SharedToGetter->Read(Index)[Axis] : ToGetter ? ToGetter->Read(Index) : ToConstant; - - switch (From) - { - default: - case EPCGExJustifyFrom::Min: - Start = OutCenter[Axis] - HalfOutSize; - break; - case EPCGExJustifyFrom::Center: - Start = OutCenter[Axis]; - break; - case EPCGExJustifyFrom::Max: - Start = OutCenter[Axis] + HalfOutSize; - break; - case EPCGExJustifyFrom::Custom: - Start = OutCenter[Axis] - HalfOutSize + (OutSize[Axis] * FromValue); - break; - case EPCGExJustifyFrom::Pivot: - Start = 0; - break; - } - - switch (To) - { - default: - case EPCGExJustifyTo::Min: - End = InCenter[Axis] - HalfInSize; - break; - case EPCGExJustifyTo::Center: - End = InCenter[Axis]; - break; - case EPCGExJustifyTo::Max: - End = InCenter[Axis] + HalfInSize; - break; - case EPCGExJustifyTo::Custom: - End = InCenter[Axis] - HalfInSize + (InSize[Axis] * ToValue); - break; - case EPCGExJustifyTo::Same: - // == Custom but using From values - End = InCenter[Axis] - HalfInSize * (InSize[Axis] * FromValue); - break; - case EPCGExJustifyTo::Pivot: - End = 0; - break; - } - - OutTranslation[Axis] = End - Start; - } + FVector& OutTranslation) const; }; USTRUCT(BlueprintType) @@ -395,74 +237,10 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExJustificationDetails const int32 Index, const FBox& InBounds, const FBox& OutBounds, - FVector& OutTranslation) const - { - const FVector InCenter = InBounds.GetCenter(); - const FVector InSize = InBounds.GetSize(); - - const FVector OutCenter = OutBounds.GetCenter(); - const FVector OutSize = OutBounds.GetSize(); - - if (bDoJustifyX) { JustifyX.JustifyAxis(0, Index, InCenter, InSize, OutCenter, OutSize, OutTranslation); } - if (bDoJustifyY) { JustifyY.JustifyAxis(1, Index, InCenter, InSize, OutCenter, OutSize, OutTranslation); } - if (bDoJustifyZ) { JustifyZ.JustifyAxis(2, Index, InCenter, InSize, OutCenter, OutSize, OutTranslation); } - } - - bool Init(FPCGExContext* InContext, const TSharedRef& InDataFacade) - { - if (bSharedCustomFromAttribute) - { - SharedFromGetter = InDataFacade->GetScopedBroadcaster(CustomFromVectorAttribute); - } + FVector& OutTranslation) const; - if (bSharedCustomToAttribute) - { - SharedToGetter = InDataFacade->GetScopedBroadcaster(CustomToVectorAttribute); - } - if (bDoJustifyX) - { - if (JustifyX.From == EPCGExJustifyFrom::Pivot && (JustifyX.To == EPCGExJustifyTo::Pivot || JustifyX.To == EPCGExJustifyTo::Same)) - { - bDoJustifyX = false; - } - else - { - JustifyX.SharedFromGetter = SharedFromGetter; - JustifyX.SharedToGetter = SharedToGetter; - if (!JustifyX.Init(InContext, InDataFacade)) { return false; } - } - } - - if (bDoJustifyY) - { - if (JustifyY.From == EPCGExJustifyFrom::Pivot && (JustifyY.To == EPCGExJustifyTo::Pivot || JustifyY.To == EPCGExJustifyTo::Same)) - { - bDoJustifyY = false; - } - else - { - JustifyY.SharedFromGetter = SharedFromGetter; - JustifyY.SharedToGetter = SharedToGetter; - if (!JustifyY.Init(InContext, InDataFacade)) { return false; } - } - } - - if (bDoJustifyZ) - { - if (JustifyZ.From == EPCGExJustifyFrom::Pivot && (JustifyZ.To == EPCGExJustifyTo::Pivot || JustifyZ.To == EPCGExJustifyTo::Same)) - { - bDoJustifyZ = false; - } - else - { - JustifyZ.SharedFromGetter = SharedFromGetter; - JustifyZ.SharedToGetter = SharedToGetter; - if (!JustifyZ.Init(InContext, InDataFacade)) { return false; } - } - } - return true; - } + bool Init(FPCGExContext* InContext, const TSharedRef& InDataFacade); }; USTRUCT(BlueprintType) @@ -521,72 +299,12 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExFittingVariationsDetails bool bEnabledAfter = true; int Seed = 0; - void Init(const int InSeed) - { - Seed = InSeed; - bEnabledBefore = (Offset == EPCGExVariationMode::Before || Rotation != EPCGExVariationMode::Before || Scale != EPCGExVariationMode::Before); - bEnabledAfter = (Offset == EPCGExVariationMode::After || Rotation != EPCGExVariationMode::After || Scale != EPCGExVariationMode::After); - } + void Init(const int InSeed); void Apply( FPCGPoint& InPoint, const FPCGExFittingVariations& Variations, - const EPCGExVariationMode& Step) const - { - FRandomStream RandomSource(PCGExRandom::ComputeSeed(Seed, InPoint.Seed)); - - FVector RandomScale = FVector::OneVector; - FVector RandomOffset = FVector::ZeroVector; - FQuat RandomRotation = FQuat::Identity; - const FTransform SourceTransform = InPoint.Transform; - - if (Offset == Step) - { - const float OffsetX = RandomSource.FRandRange(Variations.OffsetMin.X, Variations.OffsetMax.X); - const float OffsetY = RandomSource.FRandRange(Variations.OffsetMin.Y, Variations.OffsetMax.Y); - const float OffsetZ = RandomSource.FRandRange(Variations.OffsetMin.Z, Variations.OffsetMax.Z); - RandomOffset = FVector(OffsetX, OffsetY, OffsetZ); - } - - if (Rotation == Step) - { - const float RotationX = RandomSource.FRandRange(Variations.RotationMin.Pitch, Variations.RotationMax.Pitch); - const float RotationY = RandomSource.FRandRange(Variations.RotationMin.Yaw, Variations.RotationMax.Yaw); - const float RotationZ = RandomSource.FRandRange(Variations.RotationMin.Roll, Variations.RotationMax.Roll); - RandomRotation = FQuat(FRotator(RotationX, RotationY, RotationZ).Quaternion()); - } - - if (Scale == Step) - { - if (Variations.bUniformScale) - { - RandomScale = FVector(RandomSource.FRandRange(Variations.ScaleMin.X, Variations.ScaleMax.X)); - } - else - { - RandomScale.X = RandomSource.FRandRange(Variations.ScaleMin.X, Variations.ScaleMax.X); - RandomScale.Y = RandomSource.FRandRange(Variations.ScaleMin.Y, Variations.ScaleMax.Y); - RandomScale.Z = RandomSource.FRandRange(Variations.ScaleMin.Z, Variations.ScaleMax.Z); - } - } - - FTransform FinalTransform = SourceTransform; - - if (Variations.bAbsoluteOffset) - { - FinalTransform.SetLocation(SourceTransform.GetLocation() + RandomOffset); - } - else - { - const FTransform RotatedTransform(SourceTransform.GetRotation()); - FinalTransform.SetLocation(SourceTransform.GetLocation() + RotatedTransform.TransformPosition(RandomOffset)); - } - - FinalTransform.SetRotation(SourceTransform.GetRotation() * RandomRotation); - FinalTransform.SetScale3D(SourceTransform.GetScale3D() * RandomScale); - - InPoint.Transform = FinalTransform; - } + const EPCGExVariationMode& Step) const; }; USTRUCT(BlueprintType) @@ -610,11 +328,7 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExFittingDetailsHandler TSharedPtr TargetDataFacade; - bool Init(FPCGExContext* InContext, const TSharedRef& InTargetFacade) - { - TargetDataFacade = InTargetFacade; - return Justification.Init(InContext, InTargetFacade); - } + bool Init(FPCGExContext* InContext, const TSharedRef& InTargetFacade); template void ComputeTransform(const int32 TargetIndex, FTransform& OutTransform, FBox& InOutBounds) const @@ -661,4 +375,4 @@ struct /*PCGEXTENDEDTOOLKIT_API*/ FPCGExTransformDetails : public FPCGExFittingD /** If enabled, copied points will be rotated by the target' rotation. */ UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, DisplayAfter="bInheritScale")) bool bInheritRotation = false; -}; \ No newline at end of file +}; diff --git a/Source/PCGExtendedToolkit/Public/Shapes/PCGExShapes.h b/Source/PCGExtendedToolkit/Public/Shapes/PCGExShapes.h index c5a8f3c57..cb5cda6fa 100644 --- a/Source/PCGExtendedToolkit/Public/Shapes/PCGExShapes.h +++ b/Source/PCGExtendedToolkit/Public/Shapes/PCGExShapes.h @@ -4,7 +4,7 @@ #pragma once #include "CoreMinimal.h" -#include "AssetStaging/PCGExFitting.h" +#include "PCGExFitting.h" #include "Data/PCGExData.h" #include "PCGExShapes.generated.h"