| | | 1 | | //======================================================================= |
| | | 2 | | // ConvexContactCandidate.cs |
| | | 3 | | //======================================================================= |
| | | 4 | | // MIT License, Copyright (c) 2024-present David Oravsky (mrdav30) |
| | | 5 | | // See LICENSE file in the project root for full license information. |
| | | 6 | | //======================================================================= |
| | | 7 | | |
| | | 8 | | using System; |
| | | 9 | | |
| | | 10 | | namespace FixedMathSharp.Geometry; |
| | | 11 | | |
| | | 12 | | /// <summary> |
| | | 13 | | /// A nonzero normal a+b sqrt(K) and signed raw gap |
| | | 14 | | /// GapSign sqrt((A+B sqrt(C))/D), with positive D and nonnegative radicand. |
| | | 15 | | /// </summary> |
| | | 16 | | /// <remarks> |
| | | 17 | | /// Each little-endian magnitude occupies the caller-selected field width (forty words by default). Slots 0..2 are a, |
| | | 18 | | /// 3..5 are b, 6 is K, and 7..10 are A, B, C, D. Signs 0..5, 7, and 8 |
| | | 19 | | /// are -1, 0, or 1, with zero sign exactly for zero magnitude; unused |
| | | 20 | | /// signs do not affect the value. GapSign is zero exactly when the gap is |
| | | 21 | | /// zero. Builders prove these invariants before admission; this view neither |
| | | 22 | | /// copies nor mutates their borrowed storage. |
| | | 23 | | /// </remarks> |
| | | 24 | | internal readonly ref struct ConvexContactCandidate |
| | | 25 | | { |
| | | 26 | | internal const int Words = 40; |
| | | 27 | | internal const int Slots = 11; |
| | | 28 | | |
| | | 29 | | internal ConvexContactCandidate(ReadOnlySpan<ulong> values, ReadOnlySpan<int> signs, int gapSign, int fieldWords = W |
| | | 30 | | { |
| | 240304 | 31 | | _fieldWords = fieldWords; |
| | 240304 | 32 | | Values = values; |
| | 240304 | 33 | | Signs = signs; |
| | 240304 | 34 | | GapSign = gapSign; |
| | 240304 | 35 | | } |
| | | 36 | | |
| | | 37 | | private readonly int _fieldWords; |
| | | 38 | | internal ReadOnlySpan<ulong> Values { get; } |
| | | 39 | | internal ReadOnlySpan<int> Signs { get; } |
| | | 40 | | internal int GapSign { get; } |
| | 34407 | 41 | | internal ReadOnlySpan<ulong> NormalRational(int component) => Slot(component); |
| | 34386 | 42 | | internal ReadOnlySpan<ulong> NormalRadical(int component) => Slot(component + 3); |
| | 43277 | 43 | | internal ReadOnlySpan<ulong> NormalRadicand => Slot(6); |
| | 475465 | 44 | | internal ReadOnlySpan<ulong> GapRational => Slot(7); |
| | 235346 | 45 | | internal int GapRationalSign => Signs[7]; |
| | 473972 | 46 | | internal ReadOnlySpan<ulong> GapRadical => Slot(8); |
| | 234237 | 47 | | internal int GapRadicalSign => Signs[8]; |
| | 236994 | 48 | | internal ReadOnlySpan<ulong> GapRadicand => Slot(9); |
| | 917437 | 49 | | internal ReadOnlySpan<ulong> GapDenominator => Slot(10); |
| | 2215938 | 50 | | private ReadOnlySpan<ulong> Slot(int slot) => Values.Slice(slot * _fieldWords, _fieldWords); |
| | | 51 | | } |