Skip to content

Commit f6874e3

Browse files
committed
Gimbal lock fix for spline meshes
1 parent a0cbc08 commit f6874e3

9 files changed

Lines changed: 23 additions & 9 deletions

File tree

Content/Assets/Debug/LV_Debug.umap

26.3 KB
Binary file not shown.
48 KB
Binary file not shown.
131 KB
Binary file not shown.
26.3 KB
Binary file not shown.

Plugins/PCGExtendedToolkit/Source/PCGExtendedToolkit/Private/Paths/PCGExPathSplineMesh.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ namespace PCGExPathSplineMesh
354354
Segment.Params.StartTangent = LeaveReader->Read(Index);
355355
Segment.Params.EndTangent = ArriveReader->Read(NextIndex);
356356
}
357+
358+
if (Settings->bFixGimbalLock) { Segment.FixGimbalLock(); }
357359
}
358360

359361
void FProcessor::CompleteWork()

Plugins/PCGExtendedToolkit/Source/PCGExtendedToolkit/Private/Paths/PCGExPathSplineMeshSimple.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ namespace PCGExPathSplineMeshSimple
256256
Segment.Params.StartTangent = LeaveReader->Read(Index);
257257
Segment.Params.EndTangent = ArriveReader->Read(NextIndex);
258258
}
259+
260+
if (Settings->bFixGimbalLock) { Segment.FixGimbalLock(); }
259261
}
260262

261263
void FProcessor::CompleteWork()

Plugins/PCGExtendedToolkit/Source/PCGExtendedToolkit/Public/Paths/PCGExPathSplineMesh.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,6 @@ class /*PCGEXTENDEDTOOLKIT_API*/ UPCGExPathSplineMeshSettings : public UPCGExPat
7272
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Distribution", meta=(PCG_Overridable))
7373
FName AssetPathAttributeName = "AssetPath";
7474

75-
/** */
76-
//UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Target Actor", meta = (PCG_Overridable))
77-
//bool bPerSegmentTargetActor = false;
78-
79-
/** */
80-
//UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Target Actor", meta=(PCG_Overridable, EditCondition="bPerSegmentTargetActor", EditConditionHides))
81-
//FName TargetActorAttributeName;
82-
8375
/** Whether to read tangents from attributes or not. */
8476
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta = (PCG_Overridable))
8577
bool bApplyCustomTangents = false;
@@ -119,6 +111,10 @@ class /*PCGEXTENDEDTOOLKIT_API*/ UPCGExPathSplineMeshSettings : public UPCGExPat
119111
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "Settings|Additional Outputs", meta=(PCG_Overridable, EditCondition="WeightToAttribute!=EPCGExWeightOutputMode::NoOutput && WeightToAttribute!=EPCGExWeightOutputMode::NormalizedToDensity && WeightToAttribute!=EPCGExWeightOutputMode::NormalizedInvertedToDensity"))
120112
FName WeightAttributeName = "AssetWeight";
121113

114+
/** Fix gimbal lock, a.k.a weirdly twisted mesh */
115+
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, DisplayName="Fix Gimbal Lock"))
116+
bool bFixGimbalLock = false;
117+
122118
/** Default static mesh config applied to spline mesh components. */
123119
UPROPERTY(EditAnywhere, Category = Settings)
124120
FPCGExStaticMeshComponentDescriptor DefaultDescriptor;

Plugins/PCGExtendedToolkit/Source/PCGExtendedToolkit/Public/Paths/PCGExPathSplineMeshSimple.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,10 @@ class /*PCGEXTENDEDTOOLKIT_API*/ UPCGExPathSplineMeshSimpleSettings : public UPC
9191
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, DisplayName="End Offset", EditCondition="EndOffsetInput==EPCGExInputValueType::Constant", EditConditionHides))
9292
FVector2D EndOffset = FVector2D::ZeroVector;
9393

94+
/** Fix gimbal lock, a.k.a weirdly twisted mesh */
95+
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable, DisplayName="Fix Gimbal Lock"))
96+
bool bFixGimbalLock = false;
97+
9498
/** */
9599
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Settings, meta=(PCG_Overridable))
96100
EPCGExMinimalAxis SplineMeshAxisConstant = EPCGExMinimalAxis::X;

Plugins/PCGExtendedToolkit/Source/PCGExtendedToolkit/Public/Paths/PCGExPaths.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,16 @@ namespace PCGExPaths
300300
const FPCGExMeshCollectionEntry* MeshEntry = nullptr;
301301
FSplineMeshParams Params;
302302

303+
void FixGimbalLock()
304+
{
305+
// Thanks Drakynfly @ https://www.reddit.com/r/unrealengine/comments/kqo6ez/usplinecomponent_twists_in_on_itself/
306+
307+
const FVector NormalA = Params.StartTangent.GetSafeNormal(0.001);
308+
const FVector NormalB = Params.EndTangent.GetSafeNormal(0.001);
309+
if (const float Dot = NormalA | NormalB; Dot > 0.99 || Dot <= -0.99) { UpVector = NormalA; }
310+
else { UpVector = NormalA ^ NormalB; }
311+
}
312+
303313
void ApplySettings(USplineMeshComponent* Component) const
304314
{
305315
check(Component)
@@ -315,7 +325,7 @@ namespace PCGExPaths
315325
else { Component->SetEndRoll(Params.EndRoll, false); }
316326

317327
Component->SetForwardAxis(SplineMeshAxis, false);
318-
Component->SetSplineUpDir(FVector::UpVector, false);
328+
Component->SetSplineUpDir(UpVector, false);
319329

320330
Component->SetStartOffset(Params.StartOffset, false);
321331
Component->SetEndOffset(Params.EndOffset, false);

0 commit comments

Comments
 (0)