< Summary

Information
Class: Gravitas.CollisionHandling.ContactAnchor
Assembly: Gravitas
File(s): /home/runner/work/Gravitas/Gravitas/src/Gravitas/CollisionHandling/Contacts/3D/ContactAnchor.cs
Line coverage
100%
Covered lines: 61
Uncovered lines: 0
Coverable lines: 61
Total lines: 221
Line coverage: 100%
Branch coverage
100%
Covered branches: 6
Total branches: 6
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%22100%
get_Origin()100%11100%
get_Rotation()100%11100%
get_IsValid()100%11100%
get_LocalPoint()100%11100%
get_LocalDisplacement()100%11100%
CompareLocalFeature(...)100%11100%
GetLocalFeatureHash64()100%11100%
get_Offset()100%11100%
FromWorldPoint(...)100%11100%
TryGetWorldPoint(...)100%11100%
TryGetOffset(...)100%11100%
TryGetOffsetFrom(...)100%11100%
TryGetOffsetFrom(...)100%11100%
GetLeverFrom(...)100%11100%
TryRebase(...)100%22100%
TryRebase(...)100%22100%

File(s)

/home/runner/work/Gravitas/Gravitas/src/Gravitas/CollisionHandling/Contacts/3D/ContactAnchor.cs

#LineLine coverage
 1//=======================================================================
 2// ContactAnchor.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 System.Runtime.CompilerServices;
 11
 12namespace Gravitas.CollisionHandling;
 13
 14/// <summary>
 15/// Represents a 3D contact point in one rigid world-space frame.
 16/// </summary>
 17/// <remarks>
 18/// The underlying origin, rotation, and local point remain authoritative when
 19/// either the rotated offset or absolute world point lies outside the
 20/// <see cref="Fixed64"/> scalar range.
 21/// </remarks>
 22public readonly struct ContactAnchor
 23{
 24    private readonly FixedPointAnchor _point;
 25
 26    /// <summary>
 27    /// Creates a contact anchor in an identity-rotation rigid frame.
 28    /// </summary>
 29    public ContactAnchor(Vector3d origin, Vector3d offset)
 10698830        : this(origin, FixedQuaternion.Identity, offset)
 31    {
 10698832    }
 33
 34    /// <summary>
 35    /// Creates a contact anchor in a rigid local frame.
 36    /// </summary>
 37    public ContactAnchor(
 38        Vector3d origin,
 39        FixedQuaternion rotation,
 40        Vector3d localPoint)
 23374141        : this(origin, rotation, localPoint, Vector3d.Zero)
 42    {
 23374143    }
 44
 45    /// <summary>
 46    /// Creates a contact anchor whose two local terms remain separate until
 47    /// the exact rotated point is evaluated.
 48    /// </summary>
 49    public ContactAnchor(
 50        Vector3d origin,
 51        FixedQuaternion rotation,
 52        Vector3d localPoint,
 53        Vector3d localDisplacement)
 54    {
 23495855        _point = new FixedPointAnchor(
 23495856            origin,
 23495857            rotation,
 23495858            localPoint,
 23495859            localDisplacement);
 23495860    }
 61
 62    /// <summary>
 63    /// Creates a physics-domain wrapper for an exact point anchor.
 64    /// </summary>
 65    public ContactAnchor(FixedPointAnchor point)
 66    {
 6798067        if (!point.Rotation.IsNormalized())
 68        {
 169            throw new System.ArgumentException(
 170                "The point anchor must contain a normalized rotation.",
 171                nameof(point));
 72        }
 73
 6797974        _point = point;
 6797975    }
 76
 77    /// <summary>
 78    /// Gets the representable world-space origin.
 79    /// </summary>
 65380    public Vector3d Origin => _point.Origin;
 81
 82    /// <summary>
 83    /// Gets the normalized local-to-world frame rotation.
 84    /// </summary>
 8141385    public FixedQuaternion Rotation => _point.Rotation;
 86
 8137387    internal bool IsValid => Rotation.IsNormalized();
 88
 89    /// <summary>
 90    /// Gets the point in the contact frame's local coordinates.
 91    /// </summary>
 4392    public Vector3d LocalPoint => _point.LocalPoint;
 93
 94    /// <summary>
 95    /// Gets the secondary local displacement retained separately from
 96    /// <see cref="LocalPoint"/>.
 97    /// </summary>
 3198    public Vector3d LocalDisplacement => _point.LocalDisplacement;
 99
 100    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 101    internal int CompareLocalFeature(in ContactAnchor other) =>
 30361102        _point.CompareLocalFeature(other._point);
 103
 104    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 105    internal ulong GetLocalFeatureHash64() =>
 60786106        _point.GetLocalFeatureHash64();
 107
 108    /// <summary>
 109    /// Gets the rotated offset from <see cref="Origin"/> to the conceptual
 110    /// contact point.
 111    /// </summary>
 112    /// <exception cref="System.InvalidOperationException">
 113    /// The rotated offset lies outside the representable coordinate domain.
 114    /// </exception>
 115    public Vector3d Offset
 116    {
 117        get
 118        {
 13119            bool succeeded = TryGetOffset(out Vector3d offset);
 13120            SwiftThrowHelper.ThrowIfTrue(
 13121                !succeeded,
 13122                nameof(Offset),
 13123                "The contact offset is outside the representable coordinate domain.");
 12124            return offset;
 125        }
 126    }
 127
 128    /// <summary>
 129    /// Creates an anchor for an already materialized world point.
 130    /// </summary>
 131    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 132    public static ContactAnchor FromWorldPoint(Vector3d point) =>
 5006133        new(Vector3d.Zero, point);
 134
 135    /// <summary>
 136    /// Attempts to materialize the absolute world point without saturation.
 137    /// </summary>
 138    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 139    public bool TryGetWorldPoint(out Vector3d point) =>
 1064140        _point.TryGetPoint(out point);
 141
 142    /// <summary>
 143    /// Attempts to obtain the rotated offset from <see cref="Origin"/> to the
 144    /// conceptual contact point.
 145    /// </summary>
 146    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 147    public bool TryGetOffset(out Vector3d offset) =>
 17148        _point.TryGetOffsetFrom(
 17149            new FixedPointAnchor(
 17150                Origin,
 17151                FixedQuaternion.Identity,
 17152                Vector3d.Zero),
 17153            out offset);
 154
 155    /// <summary>
 156    /// Attempts to rebase the conceptual point onto another origin with one
 157    /// final exact component-wise add/subtract operation.
 158    /// </summary>
 159    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 160    public bool TryGetOffsetFrom(Vector3d origin, out Vector3d offset) =>
 2012161        _point.TryGetOffsetFrom(
 2012162            new FixedPointAnchor(
 2012163                origin,
 2012164                FixedQuaternion.Identity,
 2012165                Vector3d.Zero),
 2012166            out offset);
 167
 168    /// <summary>
 169    /// Attempts to obtain this point's exact world-space offset from another
 170    /// rigid-frame contact anchor.
 171    /// </summary>
 172    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 173    public bool TryGetOffsetFrom(
 174        in ContactAnchor other,
 175        out Vector3d offset) =>
 118595176        _point.TryGetOffsetFrom(other._point, out offset);
 177
 178    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 179    internal ExactLever3D GetLeverFrom(in ContactAnchor other) =>
 4044180        ExactLever3D.Create(_point, other._point);
 181
 182    /// <summary>
 183    /// Attempts to express the same conceptual point relative to another
 184    /// representable origin.
 185    /// </summary>
 186    public bool TryRebase(Vector3d origin, out ContactAnchor anchor)
 187    {
 2188        if (!_point.TryReframe(
 2189                origin,
 2190                FixedQuaternion.Identity,
 2191                out FixedPointAnchor point))
 192        {
 1193            anchor = default;
 1194            return false;
 195        }
 196
 1197        anchor = new ContactAnchor(point);
 1198        return true;
 199    }
 200
 201    /// <summary>
 202    /// Attempts to express the same conceptual point in another rigid frame.
 203    /// </summary>
 204    public bool TryRebase(
 205        Vector3d origin,
 206        FixedQuaternion rotation,
 207        out ContactAnchor anchor)
 208    {
 3209        if (!_point.TryReframe(
 3210                origin,
 3211                rotation,
 3212                out FixedPointAnchor point))
 213        {
 1214            anchor = default;
 1215            return false;
 216        }
 217
 2218        anchor = new ContactAnchor(point);
 2219        return true;
 220    }
 221}