< Summary

Information
Class: Gravitas.Colliders.LSSphereCollider
Assembly: Gravitas
File(s): /home/runner/work/Gravitas/Gravitas/src/Gravitas/Colliders/3D/LSSphereCollider.cs
Line coverage
100%
Covered lines: 75
Uncovered lines: 0
Coverable lines: 75
Total lines: 146
Line coverage: 100%
Branch coverage
100%
Covered branches: 4
Total branches: 4
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%
get_Shape()100%11100%
get_Priority()100%11100%
OnRadiusChanged()100%11100%
get_ScaledRadius()100%11100%
PrepareShape(...)100%11100%
PublishShape()100%11100%
CalculateMassPropertyWeight()100%11100%
CalculatePreparedMassPropertyWeight()100%11100%
CalculateCenterOfMassInertiaTensor(...)100%11100%
ClosestPointOnSurface(...)100%22100%
GetNormalAtPoint(...)100%22100%
GetClosestSurfaceAnchor(...)100%11100%
ColliderOverlapsRay(...)100%11100%

File(s)

/home/runner/work/Gravitas/Gravitas/src/Gravitas/Colliders/3D/LSSphereCollider.cs

#LineLine coverage
 1//=======================================================================
 2// LSSphereCollider.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 System;
 13
 14namespace Gravitas.Colliders;
 15
 16/// <summary>Represents a runtime 3D sphere collider.</summary>
 17public sealed class LSSphereCollider : LSCollider
 18{
 297219    private Fixed64 _scaledRadius = Fixed64.Half;
 20    private Fixed64 _preparedRadius;
 21    private Fixed64 _preparedArea;
 22
 23    /// <summary>Creates a sphere collider with default dimensions.</summary>
 563624    public LSSphereCollider() { }
 25
 26    /// <summary>Creates a runtime sphere from an authored shape definition.</summary>
 15427    public LSSphereCollider(ColliderShapeDefinition definition)
 28    {
 15429        definition.EnsureKind(ColliderShapeDefinitionKind.Sphere);
 15330        Material = definition.Material;
 15331        Radius = definition.Radius;
 15332    }
 33
 34    /// <inheritdoc/>
 24034235    public override ColliderType Shape => ColliderType.Sphere;
 36
 37    /// <inheritdoc/>
 611338    public override int Priority => ColliderSettings.GetPriority(Shape);
 39
 40    /// <inheritdoc/>
 41    protected override void OnRadiusChanged()
 42    {
 38043        Fixed64 diameter = _radius * 2;
 38044        _size = new Vector3d(diameter, diameter, diameter);
 38045    }
 46
 47    /// <inheritdoc/>
 9537448    public override Fixed64 ScaledRadius => _scaledRadius;
 49
 50    private protected override void PrepareShape(in ColliderShapeSnapshot snapshot)
 51    {
 2187152        Fixed64 radiusX = ColliderScalePolicy.ScalePositive(
 2187153            snapshot.Radius,
 2187154            snapshot.OwnerScale.X,
 2187155            snapshot.PartScale.X);
 2186956        Fixed64 radiusY = ColliderScalePolicy.ScalePositive(
 2186957            snapshot.Radius,
 2186958            snapshot.OwnerScale.Y,
 2186959            snapshot.PartScale.Y);
 2186960        Fixed64 radiusZ = ColliderScalePolicy.ScalePositive(
 2186961            snapshot.Radius,
 2186962            snapshot.OwnerScale.Z,
 2186963            snapshot.PartScale.Z);
 2186964        _preparedRadius = FixedMath.Max(radiusX, FixedMath.Max(radiusY, radiusZ));
 2186965        _preparedArea = Fixed64.Pi * _preparedRadius * _preparedRadius;
 2186966        SetPreparedBounds(FixedBoundBox.FromCenterAndScopeClippedToDomain(
 2186967            snapshot.Center,
 2186968            Vector3d.One * _preparedRadius));
 2186969    }
 70
 71    private protected override void PublishShape()
 72    {
 2175973        _scaledRadius = _preparedRadius;
 2175974        Area = _preparedArea;
 2175975    }
 76
 77    internal override ExactMassWeight CalculateMassPropertyWeight() =>
 48778        ExactMassWeight.FromProduct(
 48779            Fixed64.FromFraction(4, 3) * Fixed64.Pi,
 48780            ScaledRadius,
 48781            ScaledRadius,
 48782            ScaledRadius);
 83
 84    internal override ExactMassWeight CalculatePreparedMassPropertyWeight() =>
 45685        ExactMassWeight.FromProduct(
 45686            Fixed64.FromFraction(4, 3) * Fixed64.Pi,
 45687            _preparedRadius,
 45688            _preparedRadius,
 45689            _preparedRadius);
 90
 91    internal override Fixed3x3 CalculateCenterOfMassInertiaTensor(Fixed64 mass)
 92    {
 93        // For a solid sphere, the inertia tensor is (2/5)*m*r^2 for the diagonal elements
 717994        Fixed64 diagonalElement = Fixed64.FromFraction(2, 5) * mass * ScaledRadiusSqr;
 95
 717996        Fixed3x3 tensor = new(
 717997            diagonalElement, Fixed64.Zero, Fixed64.Zero,
 717998            Fixed64.Zero, diagonalElement, Fixed64.Zero,
 717999            Fixed64.Zero, Fixed64.Zero, diagonalElement
 7179100        );
 7179101        return tensor;
 102    }
 103
 104    /// <inheritdoc/>
 105    public override Vector3d ClosestPointOnSurface(Vector3d other)
 106    {
 575107        FixedPointAnchor anchor =
 575108            GetClosestSurfaceAnchor(other, out _);
 575109        if (anchor.TryGetPoint(out Vector3d point))
 574110            return point;
 111
 1112        throw new InvalidOperationException(
 1113            "The closest sphere surface point is outside the representable coordinate domain.");
 114    }
 115
 116    /// <inheritdoc/>
 117    public override Vector3d GetNormalAtPoint(Vector3d point)
 118    {
 1642119        if (point == Center)
 3120            return Vector3d.Zero;
 121
 1639122        _ = GetClosestSurfaceAnchor(
 1639123            point,
 1639124            out Vector3d normal);
 1639125        return normal;
 126    }
 127
 128    internal override FixedPointAnchor GetClosestSurfaceAnchor(
 129        Vector3d point,
 130        out Vector3d normal) =>
 2725131        WideFiniteAxisIntersection
 2725132            .GetClosestCenteredCapsuleSurfaceAnchor(
 2725133                point,
 2725134                Center,
 2725135                FixedQuaternion.Identity,
 2725136                Vector3d.Up,
 2725137                Fixed64.Zero,
 2725138                ScaledRadius,
 2725139                Vector3d.Right,
 2725140                out normal,
 2725141                out _);
 142
 143    /// <inheritdoc/>
 144    public override bool ColliderOverlapsRay(RaycastSegmentWorker worker, ref SwiftList<Vector3d> outputIntersectionPoin
 1307145        worker.CheckSphereOverlaps(this, ref outputIntersectionPoints);
 146}