< Summary

Information
Class: Gravitas.CollisionHandling.ExactContactLever3D
Assembly: Gravitas
File(s): /home/runner/work/Gravitas/Gravitas/src/Gravitas/CollisionHandling/Response/3D/ExactContactLever3D.cs
Line coverage
100%
Covered lines: 123
Uncovered lines: 0
Coverable lines: 123
Total lines: 234
Line coverage: 100%
Branch coverage
100%
Covered branches: 18
Total branches: 18
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/CollisionHandling/Response/3D/ExactContactLever3D.cs

#LineLine coverage
 1//=======================================================================
 2// ExactContactLever3D.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;
 10
 11namespace Gravitas.CollisionHandling;
 12
 13/// <summary>
 14/// Evaluates solver products for a semantic lever that cannot be narrowed to
 15/// <see cref="Vector3d"/>.
 16/// </summary>
 17internal static class ExactContactLever3D
 18{
 19    internal static bool TryGetNormalResponse(
 20        SolidBody? bodyA,
 21        Vector3d linearVelocityA,
 22        Vector3d angularVelocityA,
 23        in ExactLever3D relativeContactPointA,
 24        SolidBody? bodyB,
 25        Vector3d linearVelocityB,
 26        Vector3d angularVelocityB,
 27        in ExactLever3D relativeContactPointB,
 28        Vector3d normal,
 29        Fixed64 restitution,
 30        Fixed64 restitutionVelocityThreshold,
 31        out ExactNormalResponse3D response)
 32    {
 5733        ExactContactResponseOperand3D first = CreateResponseOperand(
 5734            bodyA,
 5735            linearVelocityA,
 5736            angularVelocityA,
 5737            relativeContactPointA,
 5738            -normal);
 5739        ExactContactResponseOperand3D second = CreateResponseOperand(
 5740            bodyB,
 5741            linearVelocityB,
 5742            angularVelocityB,
 5743            relativeContactPointB,
 5744            normal);
 5745        return ExactContactResponseKernel.TryGetNormalResponse(
 5746            first,
 5747            second,
 5748            normal,
 5749            restitution,
 5750            restitutionVelocityThreshold,
 5751            out response);
 52    }
 53
 54    internal static bool TryGetAccumulatedNormalResponse(
 55        SolidBody? bodyA,
 56        Vector3d linearVelocityA,
 57        Vector3d angularVelocityA,
 58        in ExactLever3D relativeContactPointA,
 59        SolidBody? bodyB,
 60        Vector3d linearVelocityB,
 61        Vector3d angularVelocityB,
 62        in ExactLever3D relativeContactPointB,
 63        Vector3d normal,
 64        Fixed64 restitution,
 65        Fixed64 restitutionVelocityThreshold,
 66        Fixed64 accumulatedImpulse,
 67        Fixed64 positiveImpulseScale,
 68        Fixed64 negativeImpulseScale,
 69        out ExactNormalResponse3D response)
 70    {
 139471        ExactContactResponseOperand3D first = CreateResponseOperand(
 139472            bodyA,
 139473            linearVelocityA,
 139474            angularVelocityA,
 139475            relativeContactPointA,
 139476            -normal);
 139477        ExactContactResponseOperand3D second = CreateResponseOperand(
 139478            bodyB,
 139479            linearVelocityB,
 139480            angularVelocityB,
 139481            relativeContactPointB,
 139482            normal);
 139483        return ExactContactResponseKernel.TryGetAccumulatedNormalResponse(
 139484            first,
 139485            second,
 139486            normal,
 139487            restitution,
 139488            restitutionVelocityThreshold,
 139489            accumulatedImpulse,
 139490            positiveImpulseScale,
 139491            negativeImpulseScale,
 139492            out response);
 93    }
 94
 95    internal static ExactContactResponseOperand3D CreateResponseOperand(
 96        SolidBody? body,
 97        Vector3d linearVelocity,
 98        Vector3d angularVelocity,
 99        in ExactLever3D relativeContactPoint,
 100        Vector3d signedNormal) =>
 4646101        new(
 4646102            relativeContactPoint,
 4646103            linearVelocity,
 4646104            angularVelocity,
 4646105            body?.ProjectLinearMotion(signedNormal) ?? Vector3d.Zero,
 4646106            body?.EffectiveInverseMass ?? Fixed64.Zero,
 4646107            body?.GetConstrainedInverseInertiaTensor() ?? Fixed3x3.Zero);
 108
 109    internal static bool TryGetAngularVelocityDelta(
 110        SolidBody? body,
 111        in ExactLever3D relativeContactPoint,
 112        Vector3d impulse,
 113        out Vector3d velocityDelta)
 114    {
 99115        velocityDelta = Vector3d.Zero;
 99116        return body?.CanRotate != true
 99117            || ExactLever3D.TryGetTransformedScaledCrossProduct(
 99118                relativeContactPoint,
 99119                impulse,
 99120                body.GetConstrainedInverseInertiaTensor(),
 99121                Fixed64.One,
 99122                Fixed64.One,
 99123                Fixed64.One,
 99124                out velocityDelta);
 125    }
 126
 127    internal static bool TryGetImpulseCombinationVelocityDeltas(
 128        SolidBody? bodyA,
 129        in ExactLever3D relativeContactPointA,
 130        SolidBody? bodyB,
 131        in ExactLever3D relativeContactPointB,
 132        Vector3d firstAxis,
 133        Fixed64 firstScale,
 134        Vector3d secondAxis,
 135        Fixed64 secondScale,
 136        Vector3d thirdAxis,
 137        Fixed64 thirdScale,
 138        out Vector3d linearVelocityDeltaA,
 139        out Vector3d angularVelocityDeltaA,
 140        out Vector3d linearVelocityDeltaB,
 141        out Vector3d angularVelocityDeltaB)
 142    {
 9143        bool linearAResolved = TryGetLinearCombinationVelocityDelta(
 9144            bodyA,
 9145            -firstAxis,
 9146            firstScale,
 9147            -secondAxis,
 9148            secondScale,
 9149            -thirdAxis,
 9150            thirdScale,
 9151            out linearVelocityDeltaA);
 9152        bool angularAResolved = TryGetAngularCombinationVelocityDelta(
 9153            bodyA,
 9154            relativeContactPointA,
 9155            -firstAxis,
 9156            firstScale,
 9157            -secondAxis,
 9158            secondScale,
 9159            -thirdAxis,
 9160            thirdScale,
 9161            out angularVelocityDeltaA);
 9162        bool linearBResolved = TryGetLinearCombinationVelocityDelta(
 9163            bodyB,
 9164            firstAxis,
 9165            firstScale,
 9166            secondAxis,
 9167            secondScale,
 9168            thirdAxis,
 9169            thirdScale,
 9170            out linearVelocityDeltaB);
 9171        bool angularBResolved = TryGetAngularCombinationVelocityDelta(
 9172            bodyB,
 9173            relativeContactPointB,
 9174            firstAxis,
 9175            firstScale,
 9176            secondAxis,
 9177            secondScale,
 9178            thirdAxis,
 9179            thirdScale,
 9180            out angularVelocityDeltaB);
 9181        return linearAResolved
 9182            & angularAResolved
 9183            & linearBResolved
 9184            & angularBResolved;
 185    }
 186
 187    private static bool TryGetLinearCombinationVelocityDelta(
 188        SolidBody? body,
 189        Vector3d firstAxis,
 190        Fixed64 firstScale,
 191        Vector3d secondAxis,
 192        Fixed64 secondScale,
 193        Vector3d thirdAxis,
 194        Fixed64 thirdScale,
 195        out Vector3d velocityDelta)
 196    {
 18197        velocityDelta = Vector3d.Zero;
 18198        return body?.CanTranslate != true
 18199            || Vector3d.TryScaledLinearCombination(
 18200                body.ProjectLinearMotion(firstAxis),
 18201                firstScale,
 18202                body.ProjectLinearMotion(secondAxis),
 18203                secondScale,
 18204                body.ProjectLinearMotion(thirdAxis),
 18205                thirdScale,
 18206                body.EffectiveInverseMass,
 18207                out velocityDelta);
 208    }
 209
 210    private static bool TryGetAngularCombinationVelocityDelta(
 211        SolidBody? body,
 212        in ExactLever3D relativeContactPoint,
 213        Vector3d firstAxis,
 214        Fixed64 firstScale,
 215        Vector3d secondAxis,
 216        Fixed64 secondScale,
 217        Vector3d thirdAxis,
 218        Fixed64 thirdScale,
 219        out Vector3d velocityDelta)
 220    {
 18221        velocityDelta = Vector3d.Zero;
 18222        return body?.CanRotate != true
 18223            || ExactLever3D.TryGetTransformedWeightedCrossProduct(
 18224                    relativeContactPoint,
 18225                    firstAxis,
 18226                    firstScale,
 18227                    secondAxis,
 18228                    secondScale,
 18229                    thirdAxis,
 18230                    thirdScale,
 18231                    body.GetConstrainedInverseInertiaTensor(),
 18232                    out velocityDelta);
 233    }
 234}

Methods/Properties

TryGetNormalResponse(Gravitas.SolidBody,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Gravitas.CollisionHandling.ExactLever3D&,Gravitas.SolidBody,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Gravitas.CollisionHandling.ExactLever3D&,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,Gravitas.CollisionHandling.ExactNormalResponse3D&)
TryGetAccumulatedNormalResponse(Gravitas.SolidBody,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Gravitas.CollisionHandling.ExactLever3D&,Gravitas.SolidBody,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Gravitas.CollisionHandling.ExactLever3D&,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,FixedMathSharp.Fixed64,Gravitas.CollisionHandling.ExactNormalResponse3D&)
CreateResponseOperand(Gravitas.SolidBody,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d,Gravitas.CollisionHandling.ExactLever3D&,FixedMathSharp.Vector3d)
TryGetAngularVelocityDelta(Gravitas.SolidBody,Gravitas.CollisionHandling.ExactLever3D&,FixedMathSharp.Vector3d,FixedMathSharp.Vector3d&)
TryGetImpulseCombinationVelocityDeltas(Gravitas.SolidBody,Gravitas.CollisionHandling.ExactLever3D&,Gravitas.SolidBody,Gravitas.CollisionHandling.ExactLever3D&,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d&,FixedMathSharp.Vector3d&,FixedMathSharp.Vector3d&,FixedMathSharp.Vector3d&)
TryGetLinearCombinationVelocityDelta(Gravitas.SolidBody,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d&)
TryGetAngularCombinationVelocityDelta(Gravitas.SolidBody,Gravitas.CollisionHandling.ExactLever3D&,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d,FixedMathSharp.Fixed64,FixedMathSharp.Vector3d&)