Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
IndexOutOfRangeException in CurvySplineSegment.LocalFToDistance function
#11
(03-15-2021, 02:58 AM)mchangxe Wrote: Maybe theres some secret connection in between splines im not aware of?

That would highly surprise me, but only the investigation will say for sure. Will hopefully start working on this by the end of the week.
By the way, is "Use Threading" active in your scene's splines? If so, can you test with that option disabled?
Available for freelance work, feel free to reach out: toolbuddy.net
Please consider leaving a review for Curvy, this helps immensely. Thank you.
Reply
#12
Hi
Sorry for taking this long.
Please replace the implementation of getApproximationIndexINTERNAL with this:

Code:
public int getApproximationIndexINTERNAL(float localF, out float frag)
        {
            {
                float testFrag;
                float testIndex;
                float clampedLocalF = Mathf.Clamp01(localF);
                if (clampedLocalF == 1)
                {
                    testFrag = 1;
                    testIndex = Mathf.Max(0, Approximation.Length - 2);
                }
                else
                {
                    float testf = clampedLocalF * (Approximation.Length - 1);
                    testIndex = (int)testf;
                    testFrag = testf - testIndex;

                    if (testIndex > Approximation.Length - 2)
                        Debug.LogError($"input: {localF:R} clamped: {clampedLocalF:R} f: {testf:R} frag:{testFrag:R} index: {testIndex:R}");
                }
            }

            float f = localF / mStepSize;
            int idx = Math.Max(0, Math.Min((int)f, Approximation.Length - 2));
            frag = Mathf.Max(0, Mathf.Min(f - idx, 1));
            return idx;
        }
If my guess of what caused the bug is right, this code should do 2 things:
  • Avoid the exception. Please let me know if you still have exceptions
  • log an error message when the conditions previously leading to the exception happen. Please send me the error logs when they appear.
Thanks for your patience
Available for freelance work, feel free to reach out: toolbuddy.net
Please consider leaving a review for Curvy, this helps immensely. Thank you.
Reply
#13
Have this happening to me as well. It seem to stem from a "issue" in TFToSegment, where a calculation sometimes come VERY close to 1, causing parts of the later logic to fail with the index out of range exception

Code:
func TFToSegment() ...

            float f = tf * segmentsCount;  // This is the issue, sometimes f comes out as something super close to 1, like 0.9999994 (due to float precision)
            int idx = (int)f; // causing idx to become 0
            localF = f - idx; // localF is still 0.9999994

In my case it happens when calling TFToDistance, which causes the subcalls TFToSegment (setting localF near 1), the returned segment (probably the wrong one due to the rounding error) is used to call LocalFToDistance, again sanity checks are passed to localF being close to 1 but not 1. This ends up calling getApproximationIndexINTERNAL, which again passes sanity checks, and returns a index equal to the size of ApproximationDistances.Length, causing the exception to happen.

Wonder if most "<some float> == 1" checks would be better off replaced with Mathf.Approximately(<some float>, 1)

Edit: In our case, segmentsCount was 32, and the tf value used as input was 0.0312499981 instead of 0.3125 due to float rounding errors (which are quite common).
Reply
#14
Hi
You are absolutely right about the comparison fix. I have been fixing some of those through time in different places, but I need some day to go through all float comparisons in the code base and fix them once and for all.
One thing about Mathf.Approximately to be aware of, is that Mathf.Approximately(0, someVerySmallNonZeroValue) will return false. There are cases where I would like it to return true. For thoses cases, I use the following:
Code:
        public static bool Approximately(this float x, float y)
        {
            bool result;
            const float zeroComparaisonMargin = 0.000001f;

            float nearlyZero = Mathf.Epsilon * 8f;

            float absX = Math.Abs(x);
            float absY = Math.Abs(y);

            if (absY < nearlyZero)
                result = absX < zeroComparaisonMargin;
            else if (absX < nearlyZero)
                result = absY < zeroComparaisonMargin;
            else
                result = Mathf.Approximately(x, y);
            return result;
        }
Available for freelance work, feel free to reach out: toolbuddy.net
Please consider leaving a review for Curvy, this helps immensely. Thank you.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Errors in Built Application in CurvySplineSegment TdayMFG 7 640 04-13-2025, 09:24 AM
Last Post: _Aka_
  Disabling a CurvySplineSegment results in NullRefException Lupos 1 276 10-02-2023, 09:55 AM
Last Post: _Aka_
  Custom CurvySplineSegment prefabs Lupos 1 308 10-02-2023, 09:36 AM
Last Post: _Aka_
  Does Curvy has gameobjects pooling system function? Chanon 7 830 09-07-2023, 12:43 PM
Last Post: _Aka_

Forum Jump: