mirror of
https://github.com/sinbad/StevesUEHelpers.git
synced 2025-02-23 17:45:23 +00:00
Add GetDistanceToConvex2D function
This commit is contained in:
parent
244302781b
commit
f47d80b62e
@ -98,4 +98,56 @@ public:
|
|||||||
const FVector& ShapePos,
|
const FVector& ShapePos,
|
||||||
const FQuat& ShapeRot,
|
const FQuat& ShapeRot,
|
||||||
FMTDResult& OutResult);
|
FMTDResult& OutResult);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the distance to a convex polygon in 2D
|
||||||
|
* @param ConvexPoints Points on the convex polygon, anti-clockwise order, in local space
|
||||||
|
* @param ConvexTransform World transform for convex polygon
|
||||||
|
* @param WorldPoint Point in world space
|
||||||
|
* @return The distance to this convex polygon in 2D space. <= 0 if inside
|
||||||
|
*/
|
||||||
|
static float GetDistanceToConvex2D(const TArray<FVector2f>& ConvexPoints,
|
||||||
|
const FTransform& ConvexTransform,
|
||||||
|
const FVector& WorldPoint)
|
||||||
|
{
|
||||||
|
checkf(ConvexTransform.GetMaximumAxisScale() == ConvexTransform.GetMinimumAxisScale(), TEXT("Non-uniform scale not supported in GetDistanceToConvex2D"));
|
||||||
|
const FVector LocalPoint = ConvexTransform.InverseTransformPosition(WorldPoint);
|
||||||
|
|
||||||
|
// Assume inside until 1 or more tests show it's outside
|
||||||
|
bool bInside = true;
|
||||||
|
float ClosestOutside = 0;
|
||||||
|
float ClosestInside = -1e30f;
|
||||||
|
const int N = ConvexPoints.Num();
|
||||||
|
for (int i = 0; i < N; ++i)
|
||||||
|
{
|
||||||
|
const int OtherIdx = (i + 1) % N;
|
||||||
|
const FVector2f Edge = ConvexPoints[OtherIdx] - ConvexPoints[i];
|
||||||
|
// Simple cross procduct to get the normal
|
||||||
|
const FVector2f Normal = FVector2f(Edge.Y, -Edge.X).GetSafeNormal();
|
||||||
|
if (!Normal.IsNearlyZero())
|
||||||
|
{
|
||||||
|
const FVector2f ToPoint = FVector2f(LocalPoint.X, LocalPoint.Y) - ConvexPoints[i];
|
||||||
|
const float Dot = Normal.Dot(ToPoint);
|
||||||
|
|
||||||
|
if (Dot > 0)
|
||||||
|
{
|
||||||
|
// Outside
|
||||||
|
// When outside we want the largest separation because convex
|
||||||
|
ClosestOutside = FMath::Max(ClosestOutside, Dot);
|
||||||
|
bInside = false;
|
||||||
|
}
|
||||||
|
else if (bInside)
|
||||||
|
{
|
||||||
|
// Inside (don't bother if we've already found one outside)
|
||||||
|
// Max because negative and inside we want the closest dot
|
||||||
|
ClosestInside = FMath::Max(ClosestInside, Dot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to rescale distance back up to world scale, only uniform scale supported for simplicity
|
||||||
|
return (bInside ? ClosestInside : ClosestOutside) * ConvexTransform.GetScale3D().X;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user