< Summary

Information
Class: Gravitas.Colliders.LSMeshCollider
Assembly: Gravitas
File(s): /home/runner/work/Gravitas/Gravitas/src/Gravitas/Colliders/3D/LSMeshCollider.cs
Line coverage
100%
Covered lines: 275
Uncovered lines: 0
Coverable lines: 275
Total lines: 563
Line coverage: 100%
Branch coverage
100%
Covered branches: 66
Total branches: 66
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/Colliders/3D/LSMeshCollider.cs

#LineLine coverage
 1//=======================================================================
 2// LSMeshCollider.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.Queries;
 11using SwiftCollections;
 12using SwiftCollections.Query;
 13using System;
 14using System.Runtime.CompilerServices;
 15
 16namespace Gravitas.Colliders;
 17
 18/// <summary>Represents a runtime 3D collider backed by deterministic triangle-mesh geometry.</summary>
 19public sealed class LSMeshCollider : LSCollider
 20{
 32421    private readonly SwiftList<int> _triangleQueryBuffer = new();
 22
 23    /// <inheritdoc/>
 122524    public override ColliderType Shape => ColliderType.Mesh;
 25
 26    /// <inheritdoc/>
 27027    public override int Priority => ColliderSettings.GetPriority(Shape);
 28
 29    /// <inheritdoc/>
 3530    public override Fixed64 Area => Mesh.TotalArea;
 31
 32    /// <summary>Gets the deterministic runtime mesh geometry.</summary>
 33    public PhysicsMesh Mesh { get; private set; }
 34
 35    /// <summary>Gets the mesh collision mode.</summary>
 175136    public MeshColliderMode Mode => Mesh.Mode;
 37
 38    /// <summary>
 39    /// Gets whether the mesh's exact-position-welded triangle topology is one
 40    /// connected, consistently wound, closed two-manifold surface.
 41    /// </summary>
 142    public bool IsClosedSurface => Mesh.IsClosedSurface;
 43
 44    /// <summary>
 45    /// Determines how inertia is derived when this mesh collider is attached to a body with angular dynamics.
 46    /// </summary>
 47    public MeshInertiaPolicy InertiaPolicy { get; }
 48
 49    /// <summary>Creates a convex mesh collider from authored vertices and triangle indices.</summary>
 50    public LSMeshCollider(Vector3d[] vertices, int[] triangles)
 351        : this(vertices, triangles, MeshColliderMode.Convex, MeshInertiaPolicy.RequireClosedVolume)
 52    {
 353    }
 54
 55    /// <summary>Creates a mesh collider with an explicit collision mode.</summary>
 56    public LSMeshCollider(Vector3d[] vertices, int[] triangles, MeshColliderMode mode)
 257        : this(vertices, triangles, mode, MeshInertiaPolicy.RequireClosedVolume)
 58    {
 259    }
 60
 61    /// <summary>Creates a mesh collider with explicit collision and inertia policies.</summary>
 32462    public LSMeshCollider(
 32463        Vector3d[] vertices,
 32464        int[] triangles,
 32465        MeshColliderMode mode,
 32466        MeshInertiaPolicy inertiaPolicy)
 67    {
 32468        ValidateInertiaPolicy(inertiaPolicy);
 32469        InertiaPolicy = inertiaPolicy;
 32470        Mesh = new PhysicsMesh(vertices, triangles, Vector3d.Zero, FixedQuaternion.Identity, mode);
 32471        _offset = Mesh.LocalBounds.Center;
 32472        Mesh.UpdatePosition(_offset, FixedQuaternion.Identity);
 32473        _size = Mesh.LocalBounds.Proportions;
 32474        _radius = _size.Magnitude * Fixed64.Half;
 32475        _bounds = Mesh.Bounds;
 32476    }
 77
 78    /// <summary>Creates a runtime convex mesh from an authored shape definition.</summary>
 79    public LSMeshCollider(ColliderShapeDefinition definition)
 3180        : this(
 3181            GetVertices(definition),
 3182            GetTriangles(definition),
 3183            MeshColliderMode.Convex,
 3184            GetInertiaPolicy(definition))
 85    {
 3186        Material = definition.Material;
 3187    }
 88
 89    /// <inheritdoc/>
 90    public override Fixed64 ScaledRadius
 91    {
 92        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 93        get
 94        {
 1795            return Mesh.ScaledLocalRadius;
 96        }
 97    }
 98
 99    private protected override void PrepareShape(in ColliderShapeSnapshot snapshot)
 100    {
 292101        Mesh.PrepareTransformation(
 292102            snapshot.Center,
 292103            snapshot.Rotation,
 292104            snapshot.OwnerScale,
 292105            snapshot.PartScale,
 292106            InertiaPolicy);
 286107        if (CompoundOwner == null
 286108            && !CalculatePreparedLocalMassPoint().TryGetPoint(out _))
 109        {
 1110            throw new InvalidOperationException(
 1111                "Prepared collider mass-property point is outside the Fixed64 coordinate domain.");
 112        }
 285113        SetPreparedBounds(Mesh.PreparedBounds);
 285114    }
 115
 116    private protected override void PublishShape() =>
 284117        Mesh.PublishPreparedTransformation();
 118
 119    internal override ExactMassWeight CalculateMassPropertyWeight()
 120    {
 45121        if (InertiaPolicy == MeshInertiaPolicy.SurfaceApproximation)
 20122            return Mesh.SurfaceMassWeight;
 123
 25124        if (Mesh.TryGetClosedVolumeMassProperties(out MeshMassProperties properties, out _))
 20125            return ExactMassWeight.FromMeasure(properties.Volume);
 126
 5127        return ExactMassWeight.Zero;
 128    }
 129
 130    internal override ExactMassWeight CalculatePreparedMassPropertyWeight()
 131    {
 72132        if (InertiaPolicy == MeshInertiaPolicy.SurfaceApproximation)
 22133            return Mesh.PreparedSurfaceMassWeight;
 134
 50135        if (Mesh.TryGetPreparedClosedVolumeMassProperties(
 50136            out MeshMassProperties properties,
 50137            out _))
 138        {
 8139            return ExactMassWeight.FromMeasure(properties.Volume);
 140        }
 141
 42142        return ExactMassWeight.Zero;
 143    }
 144
 145    internal override bool SupportsMassProperties =>
 23146        InertiaPolicy == MeshInertiaPolicy.SurfaceApproximation
 23147        || Mesh.TryGetClosedVolumeMassProperties(out _, out _);
 148
 149    internal override ExactMassPoint3D CalculateLocalMassPoint()
 150    {
 151        Vector3d meshCenterOfMass;
 373152        if (InertiaPolicy == MeshInertiaPolicy.SurfaceApproximation)
 153        {
 262154            meshCenterOfMass =
 262155                Mesh.SurfaceMassProperties.CenterOfMass;
 156        }
 111157        else if (Mesh.TryGetClosedVolumeMassProperties(
 111158            out MeshMassProperties properties,
 111159            out _))
 160        {
 83161            meshCenterOfMass = properties.CenterOfMass;
 162        }
 163        else
 164        {
 28165            meshCenterOfMass = Vector3d.Zero;
 166        }
 167
 373168        return TransformRelativeMassPropertyPointExact(
 373169            meshCenterOfMass);
 170    }
 171
 172    internal override ExactMassPoint3D CalculatePreparedLocalMassPoint()
 173    {
 174        Vector3d meshCenterOfMass;
 495175        if (InertiaPolicy == MeshInertiaPolicy.SurfaceApproximation)
 176        {
 337177            meshCenterOfMass =
 337178                Mesh.PreparedSurfaceMassProperties.CenterOfMass;
 179        }
 158180        else if (Mesh.TryGetPreparedClosedVolumeMassProperties(
 158181            out MeshMassProperties properties,
 158182            out _))
 183        {
 22184            meshCenterOfMass = properties.CenterOfMass;
 185        }
 186        else
 187        {
 136188            meshCenterOfMass = Vector3d.Zero;
 189        }
 190
 495191        return TransformPreparedRelativeMassPropertyPointExact(
 495192            meshCenterOfMass);
 193    }
 194
 195    internal override Fixed3x3 CalculateCenterOfMassInertiaTensor(
 196        Fixed64 mass)
 197    {
 198        Vector3d center;
 153199        if (InertiaPolicy == MeshInertiaPolicy.SurfaceApproximation)
 200        {
 117201            center = Mesh.SurfaceMassProperties.CenterOfMass;
 202        }
 36203        else if (Mesh.TryGetClosedVolumeMassProperties(
 36204            out MeshMassProperties properties,
 36205            out _))
 206        {
 35207            center = properties.CenterOfMass;
 208        }
 209        else
 210        {
 1211            center = Vector3d.Zero;
 212        }
 213
 153214        return Mesh.CalculateInertiaTensor(
 153215            mass,
 153216            InertiaPolicy,
 153217            center);
 218    }
 219
 220    /// <inheritdoc/>
 221    public override Fixed64 GetFrontalArea(Vector3d direction) =>
 6222        Mesh.GetFrontalArea(direction);
 223
 224    /// <summary>Writes triangle indices near a world-space point into a caller-owned buffer.</summary>
 225    public void GetNearbyTriangles(Vector3d queryPoint, SwiftList<int> result)
 226    {
 1227        FixedBoundVolume queryBounds = CreateQueryBounds(queryPoint, GetMeshQueryHalfExtent());
 1228        GetTrianglesInBounds(queryBounds, result);
 1229    }
 230
 231    /// <summary>Writes triangle indices overlapping world-space bounds into a caller-owned buffer.</summary>
 232    public void GetTrianglesInBounds(FixedBoundVolume queryBounds, SwiftList<int> result)
 233    {
 2337234        Mesh.GetTrianglesInWorldBounds(queryBounds, result);
 2337235    }
 236
 237    /// <inheritdoc/>
 238    public override Vector3d ClosestPointOnSurface(Vector3d queryPoint)
 239    {
 19240        FixedPointAnchor closest =
 19241            GetClosestSurfaceAnchor(queryPoint, out _);
 19242        if (closest.TryGetPoint(out Vector3d point))
 18243            return point;
 244
 1245        throw new InvalidOperationException(
 1246            "The closest mesh point is outside the representable coordinate range.");
 247    }
 248
 249    internal override FixedPointAnchor GetClosestSurfaceAnchor(
 250        Vector3d queryPoint,
 251        out Vector3d normal)
 252    {
 164253        FindClosestPointAnchor(
 164254            queryPoint,
 164255            _triangleQueryBuffer,
 164256            out FixedPointAnchor closest,
 164257            out normal);
 164258        return closest;
 259    }
 260
 261    internal void FindClosestPointAnchor(
 262        Vector3d queryPoint,
 263        out FixedPointAnchor closest,
 264        out Vector3d normal) =>
 51265        FindClosestPointAnchor(
 51266            queryPoint,
 51267            _triangleQueryBuffer,
 51268            out closest,
 51269            out normal);
 270
 271    internal void FindClosestPointAnchor(
 272        Vector3d queryPoint,
 273        SwiftList<int> triangleBuffer,
 274        out FixedPointAnchor closest,
 275        out Vector3d normal)
 276    {
 217277        if (!Mesh.TryConvertWorldToScaledLocal(
 217278                queryPoint,
 217279                out Vector3d localQueryPoint))
 280        {
 4281            FindClosestPointWithoutLocalQuery(
 4282                queryPoint,
 4283                out closest,
 4284                out normal);
 4285            return;
 286        }
 287
 213288        Vector3d localClosest = localQueryPoint;
 213289        normal = Vector3d.Zero;
 213290        int closestTriangleIndex = -1;
 213291        _ = KeepClosestPointOnTriangle(
 213292            0,
 213293            localQueryPoint,
 213294            ref closestTriangleIndex,
 213295            ref localClosest,
 213296            ref normal);
 213297        if (localClosest == localQueryPoint)
 298        {
 52299            closest = Mesh.CreatePointAnchor(localClosest);
 52300            normal = Mesh.Rotation.Rotate(normal).Normalized;
 52301            return;
 302        }
 303
 161304        if (!TryCreateClosestPointSearchBounds(
 161305                localQueryPoint,
 161306                localClosest,
 161307                out FixedBoundVolume queryBounds))
 308        {
 2309            FindClosestPointAcrossAllTriangles(
 2310                localQueryPoint,
 2311                1,
 2312                ref closestTriangleIndex,
 2313                ref localClosest,
 2314                ref normal);
 315        }
 316        else
 317        {
 159318            Mesh.GetTrianglesInLocalBounds(queryBounds, triangleBuffer);
 2764319            for (int i = 0; i < triangleBuffer.Count; i++)
 320            {
 1223321                _ = KeepClosestPointOnTriangle(
 1223322                    triangleBuffer[i],
 1223323                    localQueryPoint,
 1223324                    ref closestTriangleIndex,
 1223325                    ref localClosest,
 1223326                    ref normal);
 327            }
 328        }
 329
 161330        closest = Mesh.CreatePointAnchor(localClosest);
 161331        normal = Mesh.Rotation.Rotate(normal).Normalized;
 161332    }
 333
 334    private void FindClosestPointWithoutLocalQuery(
 335        Vector3d queryPoint,
 336        out FixedPointAnchor closest,
 337        out Vector3d normal)
 338    {
 4339        var queryAnchor = new FixedPointAnchor(
 4340            queryPoint,
 4341            FixedQuaternion.Identity,
 4342            Vector3d.Zero);
 4343        closest = GetClosestPointAnchorOnTriangle(
 4344            0,
 4345            queryAnchor,
 4346            out normal);
 4347        for (int triangleIndex = 1;
 6348            triangleIndex < Mesh.TriangleCount;
 2349            triangleIndex++)
 350        {
 2351            FixedPointAnchor candidate = GetClosestPointAnchorOnTriangle(
 2352                triangleIndex,
 2353                queryAnchor,
 2354                out Vector3d candidateNormal);
 2355            int comparison =
 2356                queryAnchor.CompareSquaredDistance(candidate, closest);
 2357            if (comparison >= 0)
 358            {
 359                continue;
 360            }
 361
 1362            closest = candidate;
 1363            normal = candidateNormal;
 364        }
 365
 4366    }
 367
 368    private FixedPointAnchor GetClosestPointAnchorOnTriangle(
 369        int triangleIndex,
 370        in FixedPointAnchor query,
 371        out Vector3d normal)
 372    {
 6373        Mesh.GetLocalTriangleVertices(
 6374            triangleIndex,
 6375            out Vector3d first,
 6376            out Vector3d second,
 6377            out Vector3d third);
 6378        var triangle = new FixedTriangle(first, second, third);
 6379        FixedPointAnchor closest = triangle.GetClosestPointAnchor(
 6380            Mesh.Origin,
 6381            Mesh.Rotation,
 6382            query);
 6383        normal = OrientNormalTowardPoint(
 6384            Mesh.GetFaceNormalWorld(triangleIndex),
 6385            query,
 6386            closest);
 6387        return closest;
 388    }
 389
 390    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 391    private Fixed64 GetMeshQueryHalfExtent()
 392    {
 1393        Vector3d extents =
 1394            ColliderCanonicalBounds.GetMaximumAbsoluteExtents(
 1395                this,
 1396                Mesh.Origin);
 1397        return FixedMath.Max(
 1398            FixedMath.Max(extents.X, extents.Y),
 1399            extents.Z);
 400    }
 401
 402    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 403    private static FixedBoundVolume CreateQueryBounds(Vector3d center, Fixed64 halfExtent)
 404    {
 1405        Vector3d extents = Vector3d.One * halfExtent;
 1406        return new FixedBoundVolume(center - extents, center + extents);
 407    }
 408
 409    private static void ValidateInertiaPolicy(MeshInertiaPolicy inertiaPolicy)
 410    {
 324411        SwiftThrowHelper.ThrowIfArgument(
 324412            inertiaPolicy != MeshInertiaPolicy.RequireClosedVolume &&
 324413            inertiaPolicy != MeshInertiaPolicy.SurfaceApproximation,
 324414            nameof(inertiaPolicy),
 324415            "Unsupported mesh inertia policy.");
 324416    }
 417
 418    private static Vector3d[] GetVertices(ColliderShapeDefinition definition)
 419    {
 31420        definition.EnsureKind(ColliderShapeDefinitionKind.ConvexMesh);
 31421        return definition.GetMeshVerticesForRuntime();
 422    }
 423
 424    private static int[] GetTriangles(ColliderShapeDefinition definition)
 425    {
 31426        definition.EnsureKind(ColliderShapeDefinitionKind.ConvexMesh);
 31427        return definition.GetMeshTrianglesForRuntime();
 428    }
 429
 430    private static MeshInertiaPolicy GetInertiaPolicy(ColliderShapeDefinition definition)
 431    {
 31432        definition.EnsureKind(ColliderShapeDefinitionKind.ConvexMesh);
 31433        return definition.MeshInertiaPolicy;
 434    }
 435
 436    private static bool TryCreateClosestPointSearchBounds(
 437        Vector3d point,
 438        Vector3d closest,
 439        out FixedBoundVolume bounds)
 440    {
 161441        if (!Vector3d.TrySubtract(point, closest, out Vector3d delta)
 161442            || !delta.TryGetMagnitudeCeiling(out Fixed64 halfExtent)
 161443            || !Fixed64.TryAdd(
 161444                halfExtent,
 161445                Fixed64.Epsilon,
 161446                out halfExtent))
 447        {
 2448            bounds = default;
 2449            return false;
 450        }
 451
 159452        Vector3d extents = Vector3d.One * halfExtent;
 159453        Vector3d min = point - extents;
 159454        Vector3d max = point + extents;
 159455        bounds = new FixedBoundVolume(min, max);
 159456        return true;
 457    }
 458
 459    private void FindClosestPointAcrossAllTriangles(
 460        Vector3d point,
 461        int startTriangleIndex,
 462        ref int closestTriangleIndex,
 463        ref Vector3d closest,
 464        ref Vector3d normal)
 465    {
 6466        for (int i = startTriangleIndex; i < Mesh.TriangleCount; i++)
 467        {
 1468            _ = KeepClosestPointOnTriangle(
 1469                i,
 1470                point,
 1471                ref closestTriangleIndex,
 1472                ref closest,
 1473                ref normal);
 474        }
 2475    }
 476
 477    private bool KeepClosestPointOnTriangle(
 478        int triangleIndex,
 479        Vector3d point,
 480        ref int closestTriangleIndex,
 481        ref Vector3d closest,
 482        ref Vector3d normal)
 483    {
 1437484        Mesh.GetLocalTriangleVertices(
 1437485            triangleIndex,
 1437486            out Vector3d first,
 1437487            out Vector3d second,
 1437488            out Vector3d third);
 1437489        var triangle = new FixedTriangle(first, second, third);
 1437490        Vector3d faceNormal = triangle.Normal;
 1437491        Vector3d pointOnTriangle = triangle.ClosestPoint(point);
 1437492        if (closestTriangleIndex >= 0)
 493        {
 1224494            int distanceComparison = Vector3d.CompareDistanceSquared(
 1224495                point,
 1224496                pointOnTriangle,
 1224497                point,
 1224498                closest);
 1224499            if (distanceComparison > 0
 1224500                || (distanceComparison == 0 && triangleIndex >= closestTriangleIndex))
 501            {
 941502                return false;
 503            }
 504        }
 505
 496506        closestTriangleIndex = triangleIndex;
 496507        closest = pointOnTriangle;
 496508        normal = OrientNormalTowardPoint(faceNormal, point - pointOnTriangle);
 496509        return true;
 510    }
 511
 512    /// <inheritdoc/>
 513    public override Vector3d GetNormalAtPoint(Vector3d point)
 514    {
 143515        _ = GetClosestSurfaceAnchor(
 143516            point,
 143517            out Vector3d normal);
 143518        return normal;
 519    }
 520
 521    internal override bool TryGetPlanarSurfaceNormal(Vector3d point, out Vector3d normal)
 522    {
 2523        FindClosestPointAnchor(
 2524            point,
 2525            _triangleQueryBuffer,
 2526            out _,
 2527            out normal);
 2528        return true;
 529    }
 530
 531    /// <inheritdoc/>
 532    public override bool ColliderOverlapsRay(RaycastSegmentWorker worker, ref SwiftList<Vector3d> outputIntersectionPoin
 533    {
 397534        return worker.CheckMeshOverlaps(this, ref outputIntersectionPoints);
 535    }
 536
 537    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 538    private static Vector3d OrientNormalTowardPoint(Vector3d normal, Vector3d targetDirection)
 539    {
 496540        if (targetDirection.MagnitudeSquared <= Fixed64.Epsilon)
 211541            return normal;
 542
 285543        return Vector3d.Dot(normal, targetDirection) < Fixed64.Zero ? -normal : normal;
 544    }
 545
 546    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 547    private static Vector3d OrientNormalTowardPoint(
 548        Vector3d normal,
 549        in FixedPointAnchor target,
 550        in FixedPointAnchor surfacePoint)
 551    {
 6552        if (target.ProjectNonNegativeOffsetFrom(surfacePoint, normal)
 6553            > Fixed64.Zero)
 554        {
 2555            return normal;
 556        }
 557
 4558        return surfacePoint.ProjectNonNegativeOffsetFrom(target, normal)
 4559            > Fixed64.Zero
 4560            ? -normal
 4561            : normal;
 562    }
 563}

Methods/Properties

.ctor(FixedMathSharp.Vector3d[],System.Int32[],Gravitas.Colliders.MeshColliderMode,Gravitas.Colliders.MeshInertiaPolicy)
get_Shape()
get_Priority()
get_Area()
get_Mode()
get_IsClosedSurface()
.ctor(FixedMathSharp.Vector3d[],System.Int32[])
.ctor(FixedMathSharp.Vector3d[],System.Int32[],Gravitas.Colliders.MeshColliderMode)
.ctor(Gravitas.Colliders.ColliderShapeDefinition)
get_ScaledRadius()
PrepareShape(System.Runtime.InteropServices.InAttribute))
PublishShape()
CalculateMassPropertyWeight()
CalculatePreparedMassPropertyWeight()
get_SupportsMassProperties()
CalculateLocalMassPoint()
CalculatePreparedLocalMassPoint()
CalculateCenterOfMassInertiaTensor(FixedMathSharp.Fixed64)
GetFrontalArea(FixedMathSharp.Vector3d)
GetNearbyTriangles(FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<System.Int32>)
GetTrianglesInBounds(SwiftCollections.Query.FixedBoundVolume,SwiftCollections.SwiftList`1<System.Int32>)
ClosestPointOnSurface(FixedMathSharp.Vector3d)
GetClosestSurfaceAnchor(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d&)
FindClosestPointAnchor(FixedMathSharp.Vector3d,FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Vector3d&)
FindClosestPointAnchor(FixedMathSharp.Vector3d,SwiftCollections.SwiftList`1<System.Int32>,FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Vector3d&)
FindClosestPointWithoutLocalQuery(FixedMathSharp.Vector3d,FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Vector3d&)
GetClosestPointAnchorOnTriangle(System.Int32,FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Vector3d&)
GetMeshQueryHalfExtent()
CreateQueryBounds(FixedMathSharp.Vector3d,FixedMathSharp.Fixed64)
ValidateInertiaPolicy(Gravitas.Colliders.MeshInertiaPolicy)
GetVertices(Gravitas.Colliders.ColliderShapeDefinition)
GetTriangles(Gravitas.Colliders.ColliderShapeDefinition)
GetInertiaPolicy(Gravitas.Colliders.ColliderShapeDefinition)
TryCreateClosestPointSearchBounds(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,SwiftCollections.Query.FixedBoundVolume&)
FindClosestPointAcrossAllTriangles(FixedMathSharp.Vector3d,System.Int32,System.Int32&,FixedMathSharp.Vector3d&,FixedMathSharp.Vector3d&)
KeepClosestPointOnTriangle(System.Int32,FixedMathSharp.Vector3d,System.Int32&,FixedMathSharp.Vector3d&,FixedMathSharp.Vector3d&)
GetNormalAtPoint(FixedMathSharp.Vector3d)
TryGetPlanarSurfaceNormal(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d&)
ColliderOverlapsRay(Gravitas.Queries.RaycastSegmentWorker,SwiftCollections.SwiftList`1<FixedMathSharp.Vector3d>&)
OrientNormalTowardPoint(FixedMathSharp.Vector3d,FixedMathSharp.Vector3d)
OrientNormalTowardPoint(FixedMathSharp.Vector3d,FixedMathSharp.Geometry.FixedPointAnchor&,FixedMathSharp.Geometry.FixedPointAnchor&)