< Summary

Information
Class: Gravitas.CollisionHandling.ContinuousCollisionMotionSegment3D
Assembly: Gravitas
File(s): /home/runner/work/Gravitas/Gravitas/src/Gravitas/CollisionHandling/Continuous/ContinuousCollisionMotionSegment3D.cs
Line coverage
100%
Covered lines: 37
Uncovered lines: 0
Coverable lines: 37
Total lines: 107
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%
SamplePosition(...)100%11100%
SampleRotation(...)100%22100%
TryResolveMotionBound(...)100%22100%
ResolveLocalFraction(...)100%11100%

File(s)

/home/runner/work/Gravitas/Gravitas/src/Gravitas/CollisionHandling/Continuous/ContinuousCollisionMotionSegment3D.cs

#LineLine coverage
 1//=======================================================================
 2// ContinuousCollisionMotionSegment3D.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.CollisionHandling;
 11
 12internal enum ContinuousCollisionRotationPath3D : byte
 13{
 14    IntegratedAngularVelocity,
 15    KinematicSlerp
 16}
 17
 18/// <summary>
 19/// One immutable, normalized-time piece of a 3D body's prepared CCD trajectory.
 20/// </summary>
 21internal readonly struct ContinuousCollisionMotionSegment3D
 22{
 23    public ContinuousCollisionMotionSegment3D(
 24        Fixed64 startFraction,
 25        Fixed64 endFraction,
 26        Vector3d startPosition,
 27        Vector3d endPosition,
 28        Vector3d displacement,
 29        FixedQuaternion startRotation,
 30        Vector3d angularVelocity,
 31        FixedQuaternion targetRotation,
 32        Fixed64 angularDistance,
 33        ContinuousCollisionRotationPath3D rotationPath)
 34    {
 1456435        StartFraction = startFraction;
 1456436        EndFraction = endFraction;
 1456437        StartPosition = startPosition;
 1456438        EndPosition = endPosition;
 1456439        Displacement = displacement;
 1456440        StartRotation = startRotation;
 1456441        AngularVelocity = angularVelocity;
 1456442        TargetRotation = targetRotation;
 1456443        AngularDistance = angularDistance;
 1456444        RotationPath = rotationPath;
 1456445    }
 46
 47    public Fixed64 StartFraction { get; }
 48    public Fixed64 EndFraction { get; }
 49    public Vector3d StartPosition { get; }
 50    public Vector3d EndPosition { get; }
 51    public Vector3d Displacement { get; }
 52    public FixedQuaternion StartRotation { get; }
 53    public Vector3d AngularVelocity { get; }
 54    public FixedQuaternion TargetRotation { get; }
 55    public Fixed64 AngularDistance { get; }
 56    public ContinuousCollisionRotationPath3D RotationPath { get; }
 57
 58    public Vector3d SamplePosition(Fixed64 frameFraction)
 59    {
 451960        Fixed64 localFraction = ResolveLocalFraction(frameFraction);
 451961        return Vector3d.Lerp(StartPosition, EndPosition, localFraction);
 62    }
 63
 64    public FixedQuaternion SampleRotation(Fixed64 frameFraction, Fixed64 frameDeltaTime)
 65    {
 451266        Fixed64 localFraction = ResolveLocalFraction(frameFraction);
 451267        if (RotationPath == ContinuousCollisionRotationPath3D.KinematicSlerp)
 37168            return FixedQuaternion.Slerp(StartRotation, TargetRotation, localFraction).Normalized;
 69
 414170        Fixed64 elapsedTime = frameDeltaTime * (frameFraction - StartFraction);
 414171        FixedQuaternion angularVelocityQuaternion = new(
 414172            AngularVelocity.X,
 414173            AngularVelocity.Y,
 414174            AngularVelocity.Z,
 414175            Fixed64.Zero);
 414176        FixedQuaternion spin = angularVelocityQuaternion * StartRotation * Fixed64.Half * elapsedTime;
 414177        return (StartRotation + spin).Normalized;
 78    }
 79
 80    public bool TryResolveMotionBound(
 81        Fixed64 lowerFraction,
 82        Fixed64 upperFraction,
 83        Fixed64 pivotRadius,
 84        out Fixed64 motionBound)
 85    {
 396086        Fixed64 segmentSpan = EndFraction - StartFraction;
 396087        Fixed64 localSpan = (upperFraction - lowerFraction) / segmentSpan;
 396088        if (!Vector3d.TrySubtract(EndPosition, StartPosition, out Vector3d exactDisplacement))
 89        {
 190            motionBound = default;
 191            return false;
 92        }
 93
 395994        return ContinuousCollisionMath.TryResolveRotationalIntervalMotionBound(
 395995            exactDisplacement,
 395996            AngularDistance,
 395997            pivotRadius,
 395998            localSpan,
 395999            out motionBound);
 100    }
 101
 102    private Fixed64 ResolveLocalFraction(Fixed64 frameFraction)
 103    {
 9031104        Fixed64 span = EndFraction - StartFraction;
 9031105        return FixedMath.Clamp01((frameFraction - StartFraction) / span);
 106    }
 107}