< Summary

Line coverage
100%
Covered lines: 322
Uncovered lines: 0
Coverable lines: 322
Total lines: 653
Line coverage: 100%
Branch coverage
100%
Covered branches: 98
Total branches: 98
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/Gravitas/Gravitas/src/Gravitas/Queries/Mixed/FiniteSlabProjectionSweep.cs

#LineLine coverage
 1//=======================================================================
 2// FiniteSlabProjectionSweep.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2026-present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using FixedMathSharp;
 9using FixedMathSharp.Geometry;
 10using Gravitas.Colliders;
 11using Gravitas.CollisionHandling;
 12using System;
 13using System.Runtime.CompilerServices;
 14
 15namespace Gravitas.Queries;
 16
 17/// <summary>
 18/// Sweeps an X/Z circle against the projection of curved 3D targets clipped to
 19/// a finite Y slab.
 20/// </summary>
 21internal static partial class FiniteSlabProjectionSweep
 22{
 23    private const int MaxGjkIterations = 32;
 24    private const int MaxConservativeAdvancementIterations = 32;
 125    private static readonly Fixed64 DistanceTolerance = Fixed64.FromFraction(1, 1_048_576);
 126    private static readonly Fixed64 SweepContactTolerance = DistanceTolerance;
 27
 28    public static bool TrySweepCircleAgainstCapsule(
 29        Vector2d start,
 30        Vector2d end,
 31        Vector2d direction,
 32        Fixed64 length,
 33        Fixed64 radius,
 34        Fixed64 slabMinY,
 35        Fixed64 slabMaxY,
 36        LSCapsuleCollider capsule,
 37        out Fixed64 distance,
 38        int maxConservativeAdvancementIterations = MaxConservativeAdvancementIterations)
 39    {
 9240        var target = ProjectionTarget.CreateCapsule(capsule, slabMinY, slabMaxY);
 9241        return TrySweepCircle(
 9242            start,
 9243            end,
 9244            direction,
 9245            length,
 9246            radius,
 9247            target,
 9248            out distance,
 9249            maxConservativeAdvancementIterations);
 50    }
 51
 52    public static bool TrySweepCircleAgainstCylinder(
 53        Vector2d start,
 54        Vector2d end,
 55        Vector2d direction,
 56        Fixed64 length,
 57        Fixed64 radius,
 58        Fixed64 slabMinY,
 59        Fixed64 slabMaxY,
 60        LSCylinderCollider cylinder,
 61        out Fixed64 distance,
 62        int maxConservativeAdvancementIterations = MaxConservativeAdvancementIterations)
 63    {
 11064        var target = ProjectionTarget.CreateCylinder(cylinder, slabMinY, slabMaxY);
 11065        return TrySweepCircle(
 11066            start,
 11067            end,
 11068            direction,
 11069            length,
 11070            radius,
 11071            target,
 11072            out distance,
 11073            maxConservativeAdvancementIterations);
 74    }
 75
 76    public static bool TrySweepCircleAgainstCone(
 77        Vector2d start,
 78        Vector2d end,
 79        Vector2d direction,
 80        Fixed64 length,
 81        Fixed64 radius,
 82        Fixed64 slabMinY,
 83        Fixed64 slabMaxY,
 84        LSConeCollider cone,
 85        out Fixed64 distance,
 86        int maxConservativeAdvancementIterations = MaxConservativeAdvancementIterations)
 87    {
 9088        var target = ProjectionTarget.CreateCone(cone, slabMinY, slabMaxY);
 9089        return TrySweepCircle(
 9090            start,
 9091            end,
 9092            direction,
 9093            length,
 9094            radius,
 9095            target,
 9096            out distance,
 9097            maxConservativeAdvancementIterations);
 98    }
 99
 100    private static bool TrySweepCircle(
 101        Vector2d start,
 102        Vector2d end,
 103        Vector2d direction,
 104        Fixed64 length,
 105        Fixed64 radius,
 106        ProjectionTarget target,
 107        out Fixed64 distance,
 108        int maxConservativeAdvancementIterations)
 109    {
 292110        distance = Fixed64.Zero;
 292111        if (!Vector2d.TryGetMagnitude(direction, out Fixed64 directionMagnitude)
 292112            || (directionMagnitude != Fixed64.Zero
 292113                && FixedMath.Abs(directionMagnitude - Fixed64.One) > Fixed64.Epsilon)
 292114            || maxConservativeAdvancementIterations <= 0
 292115            || !target.TrySupport(Vector2d.Right, out Vector2d rightSupport))
 12116            return false;
 117
 280118        if (target.TryGetPlanarCircle(rightSupport, out Vector2d targetCenter, out Fixed64 targetRadius))
 119        {
 136120            return new FixedSegment2d(start, end)
 136121                .TryGetCircleIntersectionDistanceInterval(
 136122                    new FixedBoundCircle(targetCenter, targetRadius),
 136123                    radius,
 136124                    length,
 136125                    out distance,
 136126                    out _,
 136127                    out _,
 136128                    out _);
 129        }
 130
 144131        Fixed64 travelDistance = Fixed64.Zero;
 624132        for (int i = 0; i < maxConservativeAdvancementIterations; i++)
 133        {
 311134            Vector2d point = GetSweepPoint(start, direction, travelDistance);
 311135            if (!TryComputeDistance(point, radius, target, out PlanarGjkResult result))
 136            {
 1137                return false;
 138            }
 139
 310140            if (result.Distance <= SweepContactTolerance)
 141            {
 136142                distance = travelDistance;
 136143                return true;
 144            }
 145
 174146            Vector2d normal = result.Normal;
 174147            Fixed64 closingSpeed = -Vector2d.Dot(direction, normal);
 174148            if (closingSpeed <= Fixed64.Epsilon)
 2149                return false;
 150
 172151            Fixed64 remainingDistance = length - travelDistance;
 172152            bool reachedEndpoint = !Fixed64.TryMultiplyDivide(
 172153                    result.Distance,
 172154                    Fixed64.One,
 172155                    closingSpeed,
 172156                    out Fixed64 stepDistance)
 172157                || stepDistance > remainingDistance;
 172158            if (reachedEndpoint)
 159            {
 4160                if (!TryComputeDistance(end, radius, target, out PlanarGjkResult endpoint))
 161                {
 1162                    return false;
 163                }
 164
 3165                if (endpoint.Distance <= SweepContactTolerance)
 166                {
 1167                    distance = length;
 1168                    return true;
 169                }
 170
 2171                return false;
 172            }
 173
 168174            travelDistance += stepDistance;
 175        }
 176
 1177        return false;
 178    }
 179
 180    private static bool TryComputeDistance(
 181        Vector2d point,
 182        Fixed64 expansionRadius,
 183        ProjectionTarget target,
 184        out PlanarGjkResult result)
 185    {
 315186        Span<PlanarSupportPoint> simplex = stackalloc PlanarSupportPoint[3];
 315187        int workingShift = GjkSimplexScale.SelectThreeTermShift(
 315188            point,
 315189            target.BoundsMin,
 315190            target.BoundsMax,
 315191            expansionRadius);
 315192        Fixed64 workingScale = GjkSimplexScale.GetCoordinateScale(workingShift);
 315193        Fixed64 workingScaleSqr = workingScale * workingScale;
 315194        Fixed64 workingDistanceTolerance = DistanceTolerance * workingScale;
 315195        Fixed64 workingSegmentDegeneracyToleranceSqr = Fixed64.Epsilon * workingScaleSqr;
 315196        Fixed64 workingAreaTolerance = DistanceTolerance * workingScaleSqr;
 315197        Fixed64 workingCrossSignTolerance = Fixed64.Epsilon * workingScaleSqr;
 315198        int simplexCount = 0;
 315199        Vector2d direction = GjkSimplexScale.CreateWorkingDifference(target.Center, point, workingShift);
 315200        if (direction == Vector2d.Zero)
 1201            direction = Vector2d.Right;
 202
 315203        bool hasPreviousDistance = false;
 315204        Fixed64 previousDistance = Fixed64.Zero;
 315205        ClosestPlanarSimplexResult closest = default;
 315206        bool distanceIsRepresentable = false;
 315207        Fixed64 workingDistance = Fixed64.MaxValue;
 208
 1914209        for (int i = 0; i < MaxGjkIterations; i++)
 210        {
 957211            if (!TryCreateSupportPoint(
 957212                    point,
 957213                    expansionRadius,
 957214                    target,
 957215                    direction,
 957216                    workingShift,
 957217                    out PlanarSupportPoint support))
 218            {
 2219                result = default;
 2220                return false;
 221            }
 222
 955223            if (ContainsSupportPoint(simplex, simplexCount, support.Point))
 224                break;
 225
 824226            simplex[simplexCount++] = support;
 824227            closest = SolveClosestSimplex(
 824228                simplex,
 824229                ref simplexCount,
 824230                workingSegmentDegeneracyToleranceSqr,
 824231                workingAreaTolerance,
 824232                workingCrossSignTolerance);
 824233            distanceIsRepresentable = Vector2d.TryGetMagnitude(closest.Point, out workingDistance);
 824234            if (closest.Intersects
 824235                || (distanceIsRepresentable && workingDistance <= workingDistanceTolerance))
 236            {
 137237                result = PlanarGjkResult.Intersection;
 137238                return true;
 239            }
 240
 687241            if (hasPreviousDistance
 687242                && distanceIsRepresentable
 687243                && previousDistance - workingDistance <= Fixed64.Epsilon)
 244            {
 245                break;
 246            }
 247
 642248            hasPreviousDistance = distanceIsRepresentable;
 642249            previousDistance = workingDistance;
 642250            direction = -closest.Point;
 251        }
 252
 176253        Fixed64 distance = GjkSimplexScale.RestoreDistance(workingDistance, workingShift);
 176254        Vector2d normal = closest.Point.Normalized;
 176255        result = new PlanarGjkResult(distance, normal);
 176256        return true;
 257    }
 258
 259    private static bool TryCreateSupportPoint(
 260        Vector2d point,
 261        Fixed64 expansionRadius,
 262        ProjectionTarget target,
 263        Vector2d direction,
 264        int workingShift,
 265        out PlanarSupportPoint support)
 266    {
 957267        Vector2d supportDirection = direction.Normalized;
 957268        Vector2d targetDirection = -supportDirection;
 957269        if (!target.TrySupport(targetDirection, out Vector2d targetSupport))
 270        {
 2271            support = default;
 2272            return false;
 273        }
 274
 955275        Vector2d expansion = targetDirection * expansionRadius;
 955276        support = new PlanarSupportPoint(
 955277            GjkSimplexScale.CreateWorkingDifference(point, targetSupport, expansion, workingShift));
 955278        return true;
 279    }
 280
 281    // The authored endpoint bounds every monotonic intermediate component.
 282    private static Vector2d GetSweepPoint(
 283        Vector2d start,
 284        Vector2d direction,
 285        Fixed64 distance) =>
 311286        new(
 311287            Fixed64.MultiplyAdd(direction.X, distance, start.X),
 311288            Fixed64.MultiplyAdd(direction.Y, distance, start.Y));
 289
 290    private static ClosestPlanarSimplexResult SolveClosestSimplex(
 291        Span<PlanarSupportPoint> simplex,
 292        ref int count,
 293        Fixed64 segmentDegeneracyToleranceSqr,
 294        Fixed64 areaTolerance,
 295        Fixed64 crossSignTolerance)
 296    {
 824297        if (count == 1)
 313298            return ClosestPlanarSimplexResult.FromPoint(simplex[0].Point);
 299
 511300        if (count == 2)
 112301            return ReduceSegment(simplex, ref count, segmentDegeneracyToleranceSqr);
 302
 399303        return ReduceTriangle(
 399304            simplex,
 399305            ref count,
 399306            segmentDegeneracyToleranceSqr,
 399307            areaTolerance,
 399308            crossSignTolerance);
 309    }
 310
 311    private static ClosestPlanarSimplexResult ReduceSegment(
 312        Span<PlanarSupportPoint> simplex,
 313        ref int count,
 314        Fixed64 segmentDegeneracyToleranceSqr)
 315    {
 1294316        Vector2d a = simplex[0].Point;
 1294317        Vector2d b = simplex[1].Point;
 1294318        Span<Vector2d> scaled = stackalloc Vector2d[2];
 1294319        scaled[0] = a;
 1294320        scaled[1] = b;
 1294321        Fixed64 productScale = GjkSimplexScale.ScaleForProducts(scaled);
 1294322        Vector2d scaledA = scaled[0];
 1294323        Vector2d ab = scaled[1] - scaledA;
 1294324        Fixed64 denominator = ab.MagnitudeSquared;
 1294325        Fixed64 productScaleSqr = productScale * productScale;
 1294326        Fixed64 denominatorTolerance = segmentDegeneracyToleranceSqr * productScaleSqr;
 1294327        Fixed64 t = denominator <= denominatorTolerance
 1294328            ? Fixed64.Zero
 1294329            : FixedMath.Clamp(-Vector2d.Dot(scaledA, ab) / denominator, Fixed64.Zero, Fixed64.One);
 330
 1294331        if (t <= Fixed64.Epsilon)
 332        {
 199333            count = 1;
 199334            return ClosestPlanarSimplexResult.FromPoint(a);
 335        }
 336
 1095337        if (t >= Fixed64.One - Fixed64.Epsilon)
 338        {
 288339            simplex[0] = simplex[1];
 288340            count = 1;
 288341            return ClosestPlanarSimplexResult.FromPoint(b);
 342        }
 343
 807344        count = 2;
 807345        return ClosestPlanarSimplexResult.FromPoint(a * (Fixed64.One - t) + b * t);
 346    }
 347
 348    private static ClosestPlanarSimplexResult ReduceTriangle(
 349        Span<PlanarSupportPoint> simplex,
 350        ref int count,
 351        Fixed64 segmentDegeneracyToleranceSqr,
 352        Fixed64 areaTolerance,
 353        Fixed64 crossSignTolerance)
 354    {
 399355        Vector2d a = simplex[0].Point;
 399356        Vector2d b = simplex[1].Point;
 399357        Vector2d c = simplex[2].Point;
 399358        if (IsOriginInsideTriangle(a, b, c, areaTolerance, crossSignTolerance))
 359        {
 5360            count = 3;
 5361            return ClosestPlanarSimplexResult.Intersection;
 362        }
 363
 394364        bool hasBest = false;
 394365        int bestFirst = 0;
 394366        int bestSecond = 1;
 394367        ClosestPlanarSimplexResult best = default;
 394368        EvaluateTriangleEdge(simplex, 0, 1, segmentDegeneracyToleranceSqr, ref best, ref hasBest, ref bestFirst, ref bes
 394369        EvaluateTriangleEdge(simplex, 1, 2, segmentDegeneracyToleranceSqr, ref best, ref hasBest, ref bestFirst, ref bes
 394370        EvaluateTriangleEdge(simplex, 2, 0, segmentDegeneracyToleranceSqr, ref best, ref hasBest, ref bestFirst, ref bes
 371
 394372        PlanarSupportPoint first = simplex[bestFirst];
 394373        PlanarSupportPoint second = simplex[bestSecond];
 394374        simplex[0] = first;
 394375        simplex[1] = second;
 394376        count = 2;
 394377        return best;
 378    }
 379
 380    private static void EvaluateTriangleEdge(
 381        Span<PlanarSupportPoint> simplex,
 382        int first,
 383        int second,
 384        Fixed64 segmentDegeneracyToleranceSqr,
 385        ref ClosestPlanarSimplexResult best,
 386        ref bool hasBest,
 387        ref int bestFirst,
 388        ref int bestSecond)
 389    {
 1182390        Span<PlanarSupportPoint> edge = stackalloc PlanarSupportPoint[2];
 1182391        edge[0] = simplex[first];
 1182392        edge[1] = simplex[second];
 1182393        int edgeCount = 2;
 1182394        ClosestPlanarSimplexResult candidate = ReduceSegment(edge, ref edgeCount, segmentDegeneracyToleranceSqr);
 1182395        if (hasBest && !IsCloser(
 1182396                candidate.DistanceSqr,
 1182397                candidate.Point,
 1182398                best.DistanceSqr,
 1182399                best.Point))
 380400            return;
 401
 802402        best = candidate;
 802403        hasBest = true;
 802404        bestFirst = first;
 802405        bestSecond = second;
 802406    }
 407
 408    internal static bool IsCloser(
 409        Fixed64 candidateDistanceSqr,
 410        Vector2d candidatePoint,
 411        Fixed64 bestDistanceSqr,
 412        Vector2d bestPoint)
 413    {
 798414        if (candidateDistanceSqr != bestDistanceSqr || candidateDistanceSqr != Fixed64.MaxValue)
 791415            return candidateDistanceSqr < bestDistanceSqr;
 416
 7417        return Vector2d.CompareMagnitudeSquared(candidatePoint, bestPoint) < 0;
 418    }
 419
 420    private static bool IsOriginInsideTriangle(
 421        Vector2d a,
 422        Vector2d b,
 423        Vector2d c,
 424        Fixed64 workingAreaTolerance,
 425        Fixed64 workingCrossSignTolerance)
 426    {
 399427        Span<Vector2d> scaled = stackalloc Vector2d[3];
 399428        scaled[0] = a;
 399429        scaled[1] = b;
 399430        scaled[2] = c;
 399431        Fixed64 productScale = GjkSimplexScale.ScaleForProducts(scaled);
 399432        a = scaled[0];
 399433        b = scaled[1];
 399434        c = scaled[2];
 435
 399436        Fixed64 productScaleSqr = productScale * productScale;
 399437        Fixed64 areaTolerance = workingAreaTolerance * productScaleSqr;
 399438        if (Cross(a, b, c).Abs() <= areaTolerance)
 119439            return false;
 440
 280441        Fixed64 ab = Cross(a, b, Vector2d.Zero);
 280442        Fixed64 bc = Cross(b, c, Vector2d.Zero);
 280443        Fixed64 ca = Cross(c, a, Vector2d.Zero);
 280444        Fixed64 signTolerance = workingCrossSignTolerance * productScaleSqr;
 280445        bool hasPositive = ab > signTolerance || bc > signTolerance || ca > signTolerance;
 280446        bool hasNegative = ab < -signTolerance || bc < -signTolerance || ca < -signTolerance;
 280447        return !(hasPositive && hasNegative);
 448    }
 449
 450    private static bool ContainsSupportPoint(
 451        Span<PlanarSupportPoint> simplex,
 452        int count,
 453        Vector2d point)
 454    {
 3730455        for (int i = 0; i < count; i++)
 456        {
 1041457            if (Vector2d.TryGetDistance(simplex[i].Point, point, out Fixed64 distance)
 1041458                && distance <= Fixed64.Epsilon)
 131459                return true;
 460        }
 461
 824462        return false;
 463    }
 464
 465    private readonly struct ProjectionTarget
 466    {
 467        private readonly LSCapsuleCollider? _capsule;
 468        private readonly LSCylinderCollider? _cylinder;
 469        private readonly LSConeCollider? _cone;
 470        private readonly FixedRange _slabY;
 471        private readonly Vector2d _center;
 472        private readonly Vector3d _axis;
 473
 474        private ProjectionTarget(
 475            LSCapsuleCollider? capsule,
 476            LSCylinderCollider? cylinder,
 477            LSConeCollider? cone,
 478            Fixed64 slabMinY,
 479            Fixed64 slabMaxY,
 480            Vector2d center,
 481            Vector3d axis)
 482        {
 292483            _capsule = capsule;
 292484            _cylinder = cylinder;
 292485            _cone = cone;
 292486            _slabY = new FixedRange(slabMinY, slabMaxY);
 292487            _center = center;
 292488            _axis = axis;
 292489        }
 490
 315491        public Vector2d Center => _center;
 492
 315493        public Vector2d BoundsMin => new(TargetBoundsMin.X, TargetBoundsMin.Z);
 494
 315495        public Vector2d BoundsMax => new(TargetBoundsMax.X, TargetBoundsMax.Z);
 496
 630497        private Vector3d TargetBoundsMin => _capsule?.BoundsMin ?? _cylinder?.BoundsMin ?? _cone!.BoundsMin;
 498
 630499        private Vector3d TargetBoundsMax => _capsule?.BoundsMax ?? _cylinder?.BoundsMax ?? _cone!.BoundsMax;
 500
 501        public static ProjectionTarget CreateCapsule(LSCapsuleCollider capsule, Fixed64 slabMinY, Fixed64 slabMaxY) =>
 92502            new(
 92503                capsule,
 92504                null,
 92505                null,
 92506                slabMinY,
 92507                slabMaxY,
 92508                new Vector2d(capsule.Center.X, capsule.Center.Z),
 92509                GetRigidUpAxis(capsule.Rotation));
 510
 511        public static ProjectionTarget CreateCylinder(LSCylinderCollider cylinder, Fixed64 slabMinY, Fixed64 slabMaxY) =
 110512            new(
 110513                null,
 110514                cylinder,
 110515                null,
 110516                slabMinY,
 110517                slabMaxY,
 110518                new Vector2d(cylinder.Center.X, cylinder.Center.Z),
 110519                GetRigidUpAxis(cylinder.Rotation));
 520
 521        public static ProjectionTarget CreateCone(LSConeCollider cone, Fixed64 slabMinY, Fixed64 slabMaxY) =>
 90522            new(
 90523                null,
 90524                null,
 90525                cone,
 90526                slabMinY,
 90527                slabMaxY,
 90528                new Vector2d(cone.Center.X, cone.Center.Z),
 90529                GetRigidUpAxis(cone.Rotation));
 530
 531        public bool TrySupport(Vector2d direction, out Vector2d support)
 532        {
 1246533            Vector2d normal = direction.Normalized;
 1246534            if (_capsule != null)
 535            {
 467536                return FixedSlabProjection.TryGetCapsuleSupport(
 467537                    _capsule.Center,
 467538                    _axis,
 467539                    _capsule.AxisLength,
 467540                    _capsule.ScaledRadius,
 467541                    _slabY,
 467542                    normal,
 467543                    out support);
 544            }
 545
 779546            if (_cylinder != null)
 547            {
 459548                return FixedSlabProjection.TryGetCylinderSupport(
 459549                    _cylinder.Center,
 459550                    _axis,
 459551                    _cylinder.Height,
 459552                    _cylinder.ScaledRadius,
 459553                    _slabY,
 459554                    normal,
 459555                    out support);
 556            }
 557
 320558            return FixedSlabProjection.TryGetConeSupport(
 320559                _cone!.Center,
 320560                _axis,
 320561                _cone.Height,
 320562                _cone.ScaledRadius,
 320563                _slabY,
 320564                normal,
 320565                out support);
 566        }
 567
 568        public bool TryGetPlanarCircle(
 569            Vector2d rightSupport,
 570            out Vector2d center,
 571            out Fixed64 radius)
 572        {
 280573            if ((_axis.X != Fixed64.Zero) | (_axis.Z != Fixed64.Zero))
 574            {
 144575                center = default;
 144576                radius = default;
 144577                return false;
 578            }
 579
 136580            center = _center;
 136581            radius = rightSupport.X - _center.X;
 136582            return true;
 583        }
 584
 585    }
 586
 587    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 588    private static Vector3d GetRigidUpAxis(FixedQuaternion rotation) =>
 292589        (rotation * Vector3d.Up).Normalized;
 590
 591    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 592    private static Fixed64 Cross(Vector2d origin, Vector2d first, Vector2d second) =>
 1239593        (first.X - origin.X) * (second.Y - origin.Y) - (first.Y - origin.Y) * (second.X - origin.X);
 594
 595}

/home/runner/work/Gravitas/Gravitas/src/Gravitas/Queries/Mixed/FiniteSlabProjectionSweep.State.cs

#LineLine coverage
 1//=======================================================================
 2// FiniteSlabProjectionSweep.State.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2026-present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using FixedMathSharp;
 9
 10namespace Gravitas.Queries;
 11
 12internal static partial class FiniteSlabProjectionSweep
 13{
 14    private readonly struct PlanarSupportPoint
 15    {
 16        public PlanarSupportPoint(Vector2d point)
 17        {
 95518            Point = point;
 95519        }
 20
 21        public Vector2d Point { get; }
 22    }
 23
 24    private readonly struct PlanarGjkResult
 25    {
 26        public PlanarGjkResult(Fixed64 distance, Vector2d normal)
 27        {
 31328            Distance = distance;
 31329            Normal = normal;
 31330        }
 31
 32        public Fixed64 Distance { get; }
 33
 34        public Vector2d Normal { get; }
 35
 13736        public static PlanarGjkResult Intersection => new(Fixed64.Zero, Vector2d.Zero);
 37    }
 38
 39    private readonly struct ClosestPlanarSimplexResult
 40    {
 41        private ClosestPlanarSimplexResult(bool intersects, Vector2d point)
 42        {
 161243            Intersects = intersects;
 161244            Point = point;
 161245            DistanceSqr = point.MagnitudeSquared;
 161246        }
 47
 48        public bool Intersects { get; }
 49
 50        public Vector2d Point { get; }
 51
 52        public Fixed64 DistanceSqr { get; }
 53
 554        public static ClosestPlanarSimplexResult Intersection => new(true, Vector2d.Zero);
 55
 160756        public static ClosestPlanarSimplexResult FromPoint(Vector2d point) => new(false, point);
 57    }
 58}

Methods/Properties

.cctor()
TrySweepCircleAgainstCapsule(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,Gravitas.Colliders.LSCapsuleCollider,FixedMathSharp.Fixed64&,System.Int32)
TrySweepCircleAgainstCylinder(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,Gravitas.Colliders.LSCylinderCollider,FixedMathSharp.Fixed64&,System.Int32)
TrySweepCircleAgainstCone(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,Gravitas.Colliders.LSConeCollider,FixedMathSharp.Fixed64&,System.Int32)
TrySweepCircle(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,Gravitas.Queries.FiniteSlabProjectionSweep/ProjectionTarget,FixedMathSharp.Fixed64&,System.Int32)
TryComputeDistance(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,Gravitas.Queries.FiniteSlabProjectionSweep/ProjectionTarget,Gravitas.Queries.FiniteSlabProjectionSweep/PlanarGjkResult&)
TryCreateSupportPoint(FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,Gravitas.Queries.FiniteSlabProjectionSweep/ProjectionTarget,FixedMathSharp.Vector2d,System.Int32,Gravitas.Queries.FiniteSlabProjectionSweep/PlanarSupportPoint&)
GetSweepPoint(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64)
SolveClosestSimplex(System.Span`1<Gravitas.Queries.FiniteSlabProjectionSweep/PlanarSupportPoint>,System.Int32&,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
ReduceSegment(System.Span`1<Gravitas.Queries.FiniteSlabProjectionSweep/PlanarSupportPoint>,System.Int32&,FixedMathSharp.Fixed64)
ReduceTriangle(System.Span`1<Gravitas.Queries.FiniteSlabProjectionSweep/PlanarSupportPoint>,System.Int32&,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
EvaluateTriangleEdge(System.Span`1<Gravitas.Queries.FiniteSlabProjectionSweep/PlanarSupportPoint>,System.Int32,System.Int32,FixedMathSharp.Fixed64,Gravitas.Queries.FiniteSlabProjectionSweep/ClosestPlanarSimplexResult&,System.Boolean&,System.Int32&,System.Int32&)
IsCloser(FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d)
IsOriginInsideTriangle(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
ContainsSupportPoint(System.Span`1<Gravitas.Queries.FiniteSlabProjectionSweep/PlanarSupportPoint>,System.Int32,FixedMathSharp.Vector2d)
.ctor(Gravitas.Colliders.LSCapsuleCollider,Gravitas.Colliders.LSCylinderCollider,Gravitas.Colliders.LSConeCollider,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Vector2d,FixedMathSharp.Vector3d)
get_Center()
get_BoundsMin()
get_BoundsMax()
get_TargetBoundsMin()
get_TargetBoundsMax()
CreateCapsule(Gravitas.Colliders.LSCapsuleCollider,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
CreateCylinder(Gravitas.Colliders.LSCylinderCollider,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
CreateCone(Gravitas.Colliders.LSConeCollider,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64)
TrySupport(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d&)
TryGetPlanarCircle(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d&,FixedMathSharp.Fixed64&)
GetRigidUpAxis(FixedMathSharp.FixedQuaternion)
Cross(FixedMathSharp.Vector2d,FixedMathSharp.Vector2d,FixedMathSharp.Vector2d)
.ctor(FixedMathSharp.Vector2d)
.ctor(FixedMathSharp.Fixed64,FixedMathSharp.Vector2d)
get_Intersection()
.ctor(System.Boolean,FixedMathSharp.Vector2d)
get_Intersection()
FromPoint(FixedMathSharp.Vector2d)