Skip to content

Commit aeba24a

Browse files
committed
Find Contours glitch fix +intersections enum cleanup
1 parent 41a3401 commit aeba24a

File tree

10 files changed

+62
-89
lines changed

10 files changed

+62
-89
lines changed

Source/PCGExtendedToolkit/Private/Graph/PCGExCluster.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ namespace PCGExCluster
327327
const FVector& B = GetPos(EndNode);
328328
const FVector& C = FMath::ClosestPointOnSegment(Guide, A, B);
329329

330-
if (FVector::DotProduct((Guide - C).GetSafeNormal(), PCGExMath::GetNormalUp(A, B, Up)) < 0) { return GetEdgeStart(Edge); }
331-
return GetEdgeEnd(Edge);
330+
if (FVector::DotProduct((Guide - C).GetSafeNormal(), PCGExMath::GetNormalUp(A, B, Up)) < 0) { return GetEdgeEnd(Edge); }
331+
return GetEdgeStart(Edge);
332332
}
333333

334334
double FCluster::EdgeDistToEdge(const FEdge* A, const FEdge* B, FVector& OutP1, FVector& OutP2) const

Source/PCGExtendedToolkit/Private/Misc/Filters/PCGExPolyPathFilterFactory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ namespace PCGExPathInclusion
325325
const PCGExOctree::FItem& Item)
326326
{
327327
if (bIgnoreSelf && InParentData != nullptr) { if (InParentData == *(Datas->GetData() + Item.Index)) { return true; } }
328-
ClosestIntersection = (*(Paths->GetData() + Item.Index))->FindClosestIntersection(InDetails, Segment, PCGExMath::EIntersectionTestMode::Strict);
328+
ClosestIntersection = (*(Paths->GetData() + Item.Index))->FindClosestIntersection(InDetails, Segment);
329329
return !ClosestIntersection.bValid;
330330
});
331331

Source/PCGExtendedToolkit/Private/PCGExMath.cpp

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -66,56 +66,30 @@ namespace PCGExMath
6666
Bounds = Bounds.ExpandBy(Expansion);
6767
}
6868

69-
bool FSegment::FindIntersection(const FVector& A2, const FVector& B2, double SquaredTolerance, FVector& OutSelf, FVector& OutOther, const EIntersectionTestMode Mode) const
69+
bool FSegment::FindIntersection(const FVector& A2, const FVector& B2, const double SquaredTolerance, FVector& OutSelf, FVector& OutOther, const uint8 Strictness) const
7070
{
7171
FMath::SegmentDistToSegment(A, B, A2, B2, OutSelf, OutOther);
7272

73-
switch (Mode)
74-
{
75-
case EIntersectionTestMode::Loose:
76-
break;
77-
case EIntersectionTestMode::Strict:
78-
if (A == OutSelf || B == OutSelf || A2 == OutOther || B2 == OutOther) { return false; }
79-
break;
80-
case EIntersectionTestMode::StrictOnSelfA:
81-
if (A == OutSelf) { return false; }
82-
break;
83-
case EIntersectionTestMode::StrictOnSelfB:
84-
if (B == OutSelf) { return false; }
85-
break;
86-
case EIntersectionTestMode::StrictOnOtherA:
87-
if (A2 == OutOther) { return false; }
88-
break;
89-
case EIntersectionTestMode::StrictOnOtherB:
90-
if (B2 == OutOther) { return false; }
91-
break;
92-
case EIntersectionTestMode::LooseOnSelf:
93-
if (A2 == OutOther || B2 == OutOther) { return false; }
94-
break;
95-
case EIntersectionTestMode::LooseOnSelfA:
96-
if (B == OutSelf || A2 == OutOther || B2 == OutOther) { return false; }
97-
break;
98-
case EIntersectionTestMode::LooseOnSelfB:
99-
if (A == OutSelf || A2 == OutOther || B2 == OutOther) { return false; }
100-
break;
101-
case EIntersectionTestMode::LooseOnOther:
102-
if (A == OutSelf || B == OutSelf) { return false; }
103-
break;
104-
case EIntersectionTestMode::LooseOnOtherA:
105-
if (A == OutSelf || B == OutSelf || B2 == OutOther) { return false; }
106-
break;
107-
case EIntersectionTestMode::LooseOnOtherB:
108-
if (A == OutSelf || B == OutSelf || A2 == OutOther) { return false; }
109-
break;
110-
}
73+
if ((Strictness & static_cast<uint8>(EPCGExIntersectionStrictness::MainA)) && A == OutSelf) { return false; }
74+
if ((Strictness & static_cast<uint8>(EPCGExIntersectionStrictness::MainB)) && B == OutSelf) { return false; }
75+
if ((Strictness & static_cast<uint8>(EPCGExIntersectionStrictness::OtherA)) && A2 == OutOther) { return false; }
76+
if ((Strictness & static_cast<uint8>(EPCGExIntersectionStrictness::OtherB)) && B2 == OutOther) { return false; }
11177

11278
if (FVector::DistSquared(OutSelf, OutOther) >= SquaredTolerance) { return false; }
11379
return true;
11480
}
11581

116-
bool FSegment::FindIntersection(const FSegment& S, double SquaredTolerance, FVector& OutSelf, FVector& OutOther, const EIntersectionTestMode Mode) const
82+
bool FSegment::FindIntersection(const FSegment& S, const double SquaredTolerance, FVector& OutSelf, FVector& OutOther, const uint8 Strictness) const
11783
{
118-
return FindIntersection(S.A, S.B, SquaredTolerance, OutSelf, OutOther, Mode);
84+
FMath::SegmentDistToSegment(A, B, S.A, S.B, OutSelf, OutOther);
85+
86+
if ((Strictness & static_cast<uint8>(EPCGExIntersectionStrictness::MainA)) && A == OutSelf) { return false; }
87+
if ((Strictness & static_cast<uint8>(EPCGExIntersectionStrictness::MainB)) && B == OutSelf) { return false; }
88+
if ((Strictness & static_cast<uint8>(EPCGExIntersectionStrictness::OtherA)) && S.A == OutOther) { return false; }
89+
if ((Strictness & static_cast<uint8>(EPCGExIntersectionStrictness::OtherB)) && S.B == OutOther) { return false; }
90+
91+
if (FVector::DistSquared(OutSelf, OutOther) >= SquaredTolerance) { return false; }
92+
return true;
11993
}
12094

12195
double ConvertStringToDouble(const FString& StringToConvert)

Source/PCGExtendedToolkit/Private/Paths/PCGExExtrudeTensors.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ namespace PCGExExtrudeTensors
236236
PCGExMath::FClosestPosition Crossing(InSegment.A);
237237

238238
const int32 LastSegment = SegmentBounds.Num() - 1;
239+
const double SqrTolerance = Context->SelfPathIntersections.ToleranceSquared;
240+
const uint8 Strictness = Context->SelfPathIntersections.Strictness;
239241

240242
for (int i = 0; i < MaxSearches; i++)
241243
{
@@ -252,7 +254,7 @@ namespace PCGExExtrudeTensors
252254
FVector OutSelf = FVector::ZeroVector;
253255
FVector OutOther = FVector::ZeroVector;
254256

255-
if (!InSegment.FindIntersection(A, B, Context->SelfPathIntersections.ToleranceSquared, OutSelf, OutOther, PCGExMath::EIntersectionTestMode::Strict))
257+
if (!InSegment.FindIntersection(A, B, SqrTolerance, OutSelf, OutOther, Strictness))
256258
{
257259
OutClosestPosition.Update(OutOther);
258260
continue;

Source/PCGExtendedToolkit/Private/Paths/PCGExPaths.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -334,12 +334,14 @@ namespace PCGExPaths
334334

335335
PCGExMath::FClosestPosition FPath::FindClosestIntersection(
336336
const FPCGExPathIntersectionDetails& InDetails,
337-
const PCGExMath::FSegment& Segment, const PCGExMath::EIntersectionTestMode Mode) const
337+
const PCGExMath::FSegment& Segment) const
338338
{
339339
PCGExMath::FClosestPosition Closest(Segment.A);
340340

341341
if (!Bounds.Intersect(Segment.Bounds)) { return Closest; }
342342

343+
const uint8 Strictness = InDetails.Strictness;
344+
343345
GetEdgeOctree()->FindElementsWithBoundsTest(
344346
Segment.Bounds, [&](const FPathEdge* PathEdge)
345347
{
@@ -355,8 +357,7 @@ namespace PCGExPaths
355357
GetPos_Unsafe(PathEdge->Start),
356358
GetPos_Unsafe(PathEdge->End),
357359
InDetails.ToleranceSquared,
358-
OnSegment,
359-
OnPath, Mode))
360+
OnSegment, OnPath, Strictness))
360361
{
361362
return;
362363
}
@@ -369,13 +370,14 @@ namespace PCGExPaths
369370

370371
PCGExMath::FClosestPosition FPath::FindClosestIntersection(
371372
const FPCGExPathIntersectionDetails& InDetails,
372-
const PCGExMath::FSegment& Segment, PCGExMath::FClosestPosition& OutClosestPosition,
373-
const PCGExMath::EIntersectionTestMode Mode) const
373+
const PCGExMath::FSegment& Segment, PCGExMath::FClosestPosition& OutClosestPosition) const
374374
{
375375
PCGExMath::FClosestPosition Closest(Segment.A);
376376

377377
if (!Bounds.Intersect(Segment.Bounds)) { return Closest; }
378378

379+
const uint8 Strictness = InDetails.Strictness;
380+
379381
GetEdgeOctree()->FindElementsWithBoundsTest(
380382
Segment.Bounds, [&](const FPathEdge* PathEdge)
381383
{
@@ -391,8 +393,7 @@ namespace PCGExPaths
391393
GetPos_Unsafe(PathEdge->Start),
392394
GetPos_Unsafe(PathEdge->End),
393395
InDetails.ToleranceSquared,
394-
OnSegment,
395-
OnPath, Mode))
396+
OnSegment, OnPath, Strictness))
396397
{
397398
OutClosestPosition.Update(OnPath, -2);
398399
return;
@@ -789,16 +790,15 @@ namespace PCGExPaths
789790
PCGExMath::FClosestPosition FindClosestIntersection(
790791
const TArray<TSharedPtr<FPath>>& Paths,
791792
const FPCGExPathIntersectionDetails& InDetails,
792-
const PCGExMath::FSegment& InSegment, int32& OutPathIndex,
793-
const PCGExMath::EIntersectionTestMode Mode)
793+
const PCGExMath::FSegment& InSegment, int32& OutPathIndex)
794794
{
795795
OutPathIndex = -1;
796796

797797
PCGExMath::FClosestPosition Intersection(InSegment.A);
798798

799799
for (int i = 0; i < Paths.Num(); i++)
800800
{
801-
PCGExMath::FClosestPosition LocalIntersection = Paths[i]->FindClosestIntersection(InDetails, InSegment, Mode);
801+
PCGExMath::FClosestPosition LocalIntersection = Paths[i]->FindClosestIntersection(InDetails, InSegment);
802802
if (!LocalIntersection) { continue; }
803803
if (Intersection.Update(LocalIntersection, LocalIntersection.Index)) { OutPathIndex = i; }
804804
}
@@ -810,16 +810,15 @@ namespace PCGExPaths
810810
const TArray<TSharedPtr<FPath>>& Paths,
811811
const FPCGExPathIntersectionDetails& InDetails,
812812
const PCGExMath::FSegment& InSegment, int32& OutPathIndex,
813-
PCGExMath::FClosestPosition& OutClosestPosition,
814-
const PCGExMath::EIntersectionTestMode Mode)
813+
PCGExMath::FClosestPosition& OutClosestPosition)
815814
{
816815
OutPathIndex = -1;
817816

818817
PCGExMath::FClosestPosition Intersection(InSegment.A);
819818

820819
for (int i = 0; i < Paths.Num(); i++)
821820
{
822-
PCGExMath::FClosestPosition LocalIntersection = Paths[i]->FindClosestIntersection(InDetails, InSegment, OutClosestPosition, Mode);
821+
PCGExMath::FClosestPosition LocalIntersection = Paths[i]->FindClosestIntersection(InDetails, InSegment, OutClosestPosition);
823822

824823
if (OutClosestPosition.Index == -2) { OutClosestPosition.Index = i; }
825824

Source/PCGExtendedToolkit/Public/Misc/Filters/PCGExSegmentCrossFilter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ UENUM()
1717
enum class EPCGExSegmentCrossWinding : uint8
1818
{
1919
ToNext = 0 UMETA(DisplayName = "To Next", ToolTip="Segment is current point to next point (canon)."),
20-
ToPrev = 1 UMETA(DisplayName = "Best Fit", ToolTip="Segment is current point to previous point (inversed direction)."),
20+
ToPrev = 1 UMETA(DisplayName = "To Prev", ToolTip="Segment is current point to previous point (inversed direction)."),
2121
};
2222

2323
USTRUCT(BlueprintType)
@@ -108,7 +108,7 @@ namespace PCGExPointFilter
108108

109109
///
110110

111-
UCLASS(MinimalAPI, BlueprintType, ClassGroup = (Procedural), Category="PCGEx|Filter", meta=(PCGExNodeLibraryDoc="filters/filters-points/spatial/SegmentCross"))
111+
UCLASS(MinimalAPI, BlueprintType, ClassGroup = (Procedural), Category="PCGEx|Filter", meta=(PCGExNodeLibraryDoc="filters/filters-points/spatial/segment-cross"))
112112
class UPCGExSegmentCrossFilterProviderSettings : public UPCGExFilterProviderSettings
113113
{
114114
GENERATED_BODY()

Source/PCGExtendedToolkit/Public/PCGExHelpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ enum class EPCGExPointNativeProperties : uint8
5151
};
5252

5353
ENUM_CLASS_FLAGS(EPCGExPointNativeProperties)
54-
using EPCGExEPCGExNativePointPropertiesBitmask = TEnumAsByte<EPCGExPointNativeProperties>;
54+
using EPCGExNativePointPropertiesBitmask = TEnumAsByte<EPCGExPointNativeProperties>;
5555

5656
UCLASS(Hidden)
5757
class PCGEXTENDEDTOOLKIT_API UPCGExComponentCallback : public UObject

Source/PCGExtendedToolkit/Public/PCGExMath.h

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,22 @@ enum class EPCGExTruncateMode : uint8
3838
Floor = 3 UMETA(DisplayName = "Floor", ToolTip="Floor"),
3939
};
4040

41-
namespace PCGExMath
41+
UENUM(meta=(Bitflags, UseEnumValuesAsMaskValuesInEditor="true"))
42+
enum class EPCGExIntersectionStrictness : uint8
4243
{
43-
enum class EIntersectionTestMode : uint8
44-
{
45-
Loose = 0,
46-
Strict,
47-
StrictOnSelfA,
48-
StrictOnSelfB,
49-
StrictOnOtherA,
50-
StrictOnOtherB,
51-
LooseOnSelf,
52-
LooseOnSelfA,
53-
LooseOnSelfB,
54-
LooseOnOther,
55-
LooseOnOtherA,
56-
LooseOnOtherB,
57-
};
44+
Loose = 0 UMETA(DisplayName = "Loose", ToolTip="Consider intersections only through segment/segment distance."),
45+
MainA = 1 << 0 UMETA(DisplayName = "Strict on Main A", ToolTip="Intersections located on main segment' start point are considered invalid."),
46+
MainB = 1 << 1 UMETA(DisplayName = "Strict on Main B", ToolTip="Intersections located on main segment' end point are considered invalid."),
47+
OtherA = 1 << 2 UMETA(DisplayName = "Strict on Other A", ToolTip="Intersections located on end segment' start point are considered invalid."),
48+
OtherB = 1 << 3 UMETA(DisplayName = "Strict on Other B", ToolTip="Intersections located on end segment' end point are considered invalid."),
49+
Strict = MainA | MainB | OtherA | OtherB
50+
};
5851

52+
ENUM_CLASS_FLAGS(EPCGExIntersectionStrictness)
53+
using EPCGExIntersectionStrictnessBitmask = TEnumAsByte<EPCGExIntersectionStrictness>;
54+
55+
namespace PCGExMath
56+
{
5957
struct PCGEXTENDEDTOOLKIT_API FClosestPosition
6058
{
6159
bool bValid = false;
@@ -96,8 +94,8 @@ namespace PCGExMath
9694
double Dot(const FSegment& InSegment) const { return FVector::DotProduct(Direction, InSegment.Direction); }
9795
FVector Lerp(const double InLerp) const { return FMath::Lerp(A, B, InLerp); }
9896

99-
bool FindIntersection(const FVector& A2, const FVector& B2, double SquaredTolerance, FVector& OutSelf, FVector& OutOther, const EIntersectionTestMode Mode = EIntersectionTestMode::Strict) const;
100-
bool FindIntersection(const FSegment& S, double SquaredTolerance, FVector& OutSelf, FVector& OutOther, const EIntersectionTestMode Mode = EIntersectionTestMode::Strict) const;
97+
bool FindIntersection(const FVector& A2, const FVector& B2, const double SquaredTolerance, FVector& OutSelf, FVector& OutOther, const uint8 Strictness) const;
98+
bool FindIntersection(const FSegment& S, const double SquaredTolerance, FVector& OutSelf, FVector& OutOther, const uint8 Strictness) const;
10199
};
102100

103101
PCGEXTENDEDTOOLKIT_API

Source/PCGExtendedToolkit/Public/Paths/PCGExExtrudeTensors.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ namespace PCGExExtrudeTensors
532532

533533
PCGExMath::FClosestPosition Intersection = FindClosestIntersection(
534534
Context->ExternalPaths, Context->ExternalPathIntersections,
535-
Segment, PathIndex, PCGExMath::EIntersectionTestMode::Strict);
535+
Segment, PathIndex);
536536

537537
// Path intersection
538538
if (Intersection)
@@ -560,7 +560,7 @@ namespace PCGExExtrudeTensors
560560

561561
Intersection = FindClosestIntersection(
562562
*SolidPaths.Get(), Context->ExternalPathIntersections,
563-
Segment, PathIndex, Merge, PCGExMath::EIntersectionTestMode::Strict);
563+
Segment, PathIndex, Merge);
564564

565565
if (Settings->SelfIntersectionPriority == EPCGExSelfIntersectionPriority::Crossing)
566566
{

Source/PCGExtendedToolkit/Public/Paths/PCGExPaths.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,10 @@ struct PCGEXTENDEDTOOLKIT_API FPCGExPathIntersectionDetails
216216
double MaxAngle = 90;
217217
double MaxDot = 1;
218218

219+
/** Strictness of the intersection detection. Different modes allow for some edge cases to be considered intersection. */
220+
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_NotOverridable, Bitmask, BitmaskEnum="/Script/PCGExtendedToolkit.EPCGExIntersectionStrictness"))
221+
uint8 Strictness = static_cast<uint8>(EPCGExIntersectionStrictness::Strict);
222+
219223
bool bWantsDotCheck = false;
220224

221225
void Init();
@@ -438,13 +442,11 @@ namespace PCGExPaths
438442
virtual bool IsEdgeValid(const int32 Index) const { return IsEdgeValid(Edges[Index]); }
439443

440444
PCGExMath::FClosestPosition FindClosestIntersection(
441-
const FPCGExPathIntersectionDetails& InDetails, const PCGExMath::FSegment& Segment,
442-
const PCGExMath::EIntersectionTestMode Mode = PCGExMath::EIntersectionTestMode::Strict) const;
445+
const FPCGExPathIntersectionDetails& InDetails, const PCGExMath::FSegment& Segment) const;
443446

444447
PCGExMath::FClosestPosition FindClosestIntersection(
445448
const FPCGExPathIntersectionDetails& InDetails, const PCGExMath::FSegment& Segment,
446-
PCGExMath::FClosestPosition& OutClosestPosition,
447-
const PCGExMath::EIntersectionTestMode Mode = PCGExMath::EIntersectionTestMode::Strict) const;
449+
PCGExMath::FClosestPosition& OutClosestPosition) const;
448450

449451
void BuildEdgeOctree();
450452
void BuildPartialEdgeOctree(const TArray<int8>& Filter);
@@ -671,16 +673,14 @@ namespace PCGExPaths
671673
PCGExMath::FClosestPosition FindClosestIntersection(
672674
const TArray<TSharedPtr<FPath>>& Paths,
673675
const FPCGExPathIntersectionDetails& InDetails,
674-
const PCGExMath::FSegment& InSegment, int32& OutPathIndex,
675-
const PCGExMath::EIntersectionTestMode Mode = PCGExMath::EIntersectionTestMode::Strict);
676+
const PCGExMath::FSegment& InSegment, int32& OutPathIndex);
676677

677678
PCGEXTENDEDTOOLKIT_API
678679
PCGExMath::FClosestPosition FindClosestIntersection(
679680
const TArray<TSharedPtr<FPath>>& Paths,
680681
const FPCGExPathIntersectionDetails& InDetails,
681682
const PCGExMath::FSegment& InSegment, int32& OutPathIndex,
682-
PCGExMath::FClosestPosition& OutClosestPosition,
683-
const PCGExMath::EIntersectionTestMode Mode = PCGExMath::EIntersectionTestMode::Strict);
683+
PCGExMath::FClosestPosition& OutClosestPosition);
684684

685685
class FPolyPath : public FPath
686686
{

0 commit comments

Comments
 (0)